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?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jkrCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
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
Exploring SharePoint 2016

Explore SharePoint 2016, the web-based, collaborative platform that integrates with Microsoft Office to provide intranets, secure document management, and collaboration so you can develop your online and offline capabilities.

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
Infinity08Commented:
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Programming Languages-Other

From novice to tech pro — start learning today.