How do I stop my program from exiting "due to signal 10 (SIGBUS)"?

I'm writing a program in XCode to break text from a text file into individual tokens. When run, my code produces an error stating: "Error from Executable Runner: Program4 has exited due to signal 10 (SIGBUS)." I understand this is probably because I didn't allocate memory correctly for the pointers. The line that the debugger highlights is:

(*token) = (char *) malloc(tokenLength + 1); // first row of token has enough space for length of token + null character

How do I placate the SIGBUS?
/* system_utilities.cpp */
 
#include <iostream>
#include <fstream>
#include <string.h> 
#include "system_utilities.h"
#include "definitions.h"
 
using namespace std;
 
ifstream file; // create input stream object
 
 
char linetext[256]; // array of characters to hold 255 characters + terminating null char
int length; // variable to hold length of current line of input (num chars)
int pos = 0; // variable to hold position of last character of current input line read by getNextToken
char *word;
 
int errorcode;
 
void printError(int errorcode)
{
   switch ( errorcode )
   {
      case END_OF_FILE:
         cout << "Error: End of file has been reached." << endl;
         break;
      case FILE_NOT_OPENED:
         cout << "Error: File could not be opened." << endl;
         break;
      case TOKEN_NOT_FOUND:
         cout << "Error: Token not found." << endl;
         break;
      default:
         cout << "There is an error." << endl;
   }
}
 
int openInputFile (char fname[])
{
   file.open(fname, ios::in); // what is ios::in for?
   if (file.good())
   {
      cout << fname << " was read successfully" << endl;
      return 0; 
   }
   else
   {
      cout << "file not read successfully" << endl;
      return FILE_NOT_OPENED; 
   }
}
 
int getNextToken(char **token) 
{
   
   cout << "Get Next Token: " << endl;
   int tokenFound = 0; // whether or not a token has been found
   cout << "tokenFound: " << tokenFound << endl;
   int tokenLength = 0; // length of token
  
   while(tokenFound == 0) // when no token has been found
   {
      if(pos == 0) // if you're at the beginning of a line
      {
         int j;
         for (j = 0; j <256; j++) // set all character array values to NULL
         {
            linetext[j] = '\0';
         }
         file.getline(linetext, 256); // read in a line of text from the file
         length = strlen(linetext); // get the length of the line
		 cout << "length: " << length << endl;
      }
      
	  // recognizing single characters 
	  
	  int i;
	  for(i = pos; i < length && (tokenFound == 0); i++) // loop through whole line
	  {
         if( ((linetext[i] != ' ') && (linetext[i] != '\0')) ) // if the character is not a space or a null
		 {
			cout << "linetext[" << i << "] = " << linetext[i] << endl;
			tokenLength = i - pos + 1; // length of token = starts at pos, ends at 1
			(*token) = (char *) malloc(tokenLength + 1); // first row of token has enough space for length of token + null character
			cout << "memory allocated successfully" << endl;
			memcpy (*token, &linetext[i], tokenLength + 1); // copy token into *token
			
			// Recognize words
			while( ((linetext[i] != ' ') && (linetext[i] != '\0')) || symbol(linetext[i]) ) // delimiter: space
			{
				i++;
			}
			pos = i + tokenLength;
			tokenFound = 1;
		 }
	  }
	  
	  if(pos == length) // if you've reached the end of the line 
	  {
		pos = 0; // reset pos to 0
		cout << "resetting pos to 0. pos = " << pos << endl;
		if(file.eof()) // if you're also at the end of the file
		{
			return END_OF_FILE;
		}
	  }
	  
	}
	return 0;
}
 
int symbol(char c)
{
   if ((c == '>') || (c == '<') || (c == '/') || (c == '='))
      {
      return 1;
      }
   else
      {
      return 0;
      }
}
 
 
/* system_utilities.h */
 
int openInputFile(char fname[]); // input file name string, open file and assign to file-level ifstream variable
int getNextToken( char **token ); // finds next token in input file, allocates new space, assigns token to point to new space, copies characters
void printError(int errorcode); // prints appropriate error message
int symbol(char c);
 
/* main.cpp */
 
#include <iostream>
#include "system_utilities.h"
#include "definitions.h"
 
using namespace std;
 
char **token1;
 
int main() 
{
   openInputFile("/Users/vshen/Documents/EECS 211/Program4/onlychars.txt");
   while(getNextToken(token1) != END_OF_FILE);
   cout << "The file has been tokenized." << endl;
   return 0;
}
 
/* definitions.h */
 
#define END_OF_FILE 201 
#define FILE_NOT_OPENED 202 
#define TOKEN_NOT_FOUND 301 
#define MAX_LINE_LENGTH 255

Open in new window

vwpsAsked:
Who is Participating?
 
jkrConnect With a Mentor Commented:
You have

char **token1;

which is not assigned any memory at all. Try
 
char *token1[10000]; // room for 10000 tokens
 
int main() 
{
   openInputFile("/Users/vshen/Documents/EECS 211/Program4/onlychars.txt");
   while(getNextToken(token1) != END_OF_FILE);
   cout << "The file has been tokenized." << endl;
   return 0;
}

Open in new window

0
 
Infinity08Commented:
SIGBUS occurs due to incorrect memory operations. So, let's have a look ...

>>    while(getNextToken(token1) != END_OF_FILE);

You haven't allocated any memory for token1, and the getNextToken function dereferences the pointer :

>>                         (*token) = (char *) malloc(tokenLength + 1); // first row of token has enough space for length of token + null character
0
 
Infinity08Commented:
Oops - sorry jkr - I got distracted, and forgot to check for replies before clicking submit.
0
Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

 
vwpsAuthor Commented:
Thanks! But how would I allocate memory without setting a limit in the beginning (as in char *token1[10000];)?
0
 
jkrCommented:
That way, it won't work. You'll either need a limit at which you stop parsing or need to use a linked list, sorry.
0
 
Infinity08Connect With a Mentor Commented:
The name of the getNextToken function suggests that it should only return one token (the next one), so there shouldn't be a problem with a limit. You can just call the function repeatedly, and immediately process the returned token. You'd have to make a few changes to your current implementation, but is that what you intended to do ?
0
 
vwpsAuthor Commented:
You're right about my intentions, Infinity08. I'm bewildered by the fact that this program managed to run before I allocated memory to token1, but I'll write it off as something on my part that I changed and forgot about.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.