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?
(*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
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Oops - sorry jkr - I got distracted, and forgot to check for replies before clicking submit.
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.
>> while(getNextToken(token1)
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