Link to home
Start Free TrialLog in
Avatar of vwps
vwps

asked on

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

ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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
Oops - sorry jkr - I got distracted, and forgot to check for replies before clicking submit.
Avatar of vwps
vwps

ASKER

Thanks! But how would I allocate memory without setting a limit in the beginning (as in char *token1[10000];)?
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.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of vwps

ASKER

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.