getting seg fault and not knowing why

hi guys i made a function to create tokens from a line of input and i push those tokens into a vector of tokens. but i keep getting seg-faulted if the if the string used to create the token is a white space, unary operator, or literal. can anyone help me? i will post my code down below. im am not going to post the token class but just know that it sets, type, value and precedence depending on the string of input used to create the token.

heres the test line from the sample file im trying to read from, me.txt:
x/^*-//cos+-

heres my function :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
void tokenize()
{
	string input; // creates a string to store the input from the given file
	ifstream inputFile ("me.txt"); //reads from file
	if (inputFile) //stores input into string 
	{
		getline (inputFile, input); 
	}
	else //error message if input file is not found
	{	
		cout << "Error: no such file name or i cannot read from the file" << endl;
		cout << "this program will now terminate...\n";
		exit(1);
	}	
	string tokenInput = ""; //creates a temp string that will be passed as an argument to initialize a token's value
	vector <Token> myTokens; //creates vector of tokens
	for (int i = 0; i < input.length(); i++)
	{			
			tokenInput.push_back(input[i]);
			//cout << tokenInput <<endl;
		 //cout << tokenInput <<endl;
		if (tokenInput == "cos")
		{
			Token btoken(tokenInput);
			myTokens.push_back(btoken);
			cout << myTokens[i].getValue() << endl;	
			cout << myTokens[i].getType() << endl;	
			tokenInput = "";
		}
//IF THE STRING IS ANY OF THOSE BELOW, THE PROGRAM RUNS WITHOUT SEGFAULT BUT ANYTHING ELSE AND IT SEG FAULTS, //PLEASE HELP ME
	    if (tokenInput == "*" || tokenInput == "/" || tokenInput == "+"|| tokenInput == "^" || tokenInput == "("
			|| tokenInput == ")" || tokenInput == "-" || tokenInput == "x")
		{			
			Token atoken(tokenInput);			
			myTokens.push_back(atoken);
			cout << myTokens[i].getValue() << endl;	
			cout << myTokens[i].getType() << endl;	
			tokenInput = "";  //resets token input to empty string							
		}
		//cout << tokenInput <<endl;
			
	}		
}


heres my output :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
x
variable
/
binary operator
^
exponentiation
*
binary operator
-
binary operator
/
binary operator
/
binary operator
Segmentation fault


heres the info from the gdb debugger (im using ubuntu 9.10):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
x
variable
/
binary operator
^
exponentiation
*
binary operator
-
binary operator
/
binary operator
/
binary operator

Program received signal SIGSEGV, Segmentation fault.
0x001c519a in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&) () from /usr/lib/libstdc++.so.6


please help me, i do not know why im getting seg-faulted and its annoying, the debugge is of no help!!!!!!
Last edited on
You're using 'i' to index myTokens when you shouldn't be. This is a problem for "cos" because cos is 3 characters instead of 1, so you end up stepping out of bounds of the array.

Say, for example, the input file was just: cos

The first two iterations of the loop would do nothing (ie: myTokens.size() == 0)

On the 3rd iteration, you find the "cos" and add the Token to myTokens, but then you do myTokens[i], where i == 2 -- however myTokens.size() is only 1! IE: out of bounds of the array = bad memory access = (fortunately) segfault.

Instead of using myTokens[i], just use myTokens.back() to access the most recently pushed element. Or just use 'atoken' and 'btoken' since those are the same thing anyway:

1
2
3
4
5
			Token btoken(tokenInput);
			myTokens.push_back(btoken);
//			cout << myTokens[i].getValue() << endl; // BAD
			cout << myTokens.back().getValue() << endl;  // OK
			cout << btoken.getValue() << endl; // Also OK 

omg....thanks alot man!!!! that works. i would never have been able to figure that out. i was so focused on the fact that there was something wrong with the way that i was handling the string (b/c i had bad segfault experiences with them b4) i would have never thought that it was the vector!!!! thanks man!! i'm going to look up omg more vector operations also, since they seem to be so handy.
oh yea, i did not do

cout << btoken.getValue() << endl;

b/c i wanted to check if the vector actually contained the token. man i didn't even know that .back() gets the most recent value. again thanks alot, lifesaver!!!
Last edited on
Topic archived. No new replies allowed.