fstream getline(..) segfault

Hi all,

This is probably a rookie mistake, but I've googled by heart out for an hour now and nothing seems to fix my issue. I'm getting a segfault when I call getline(..) on an fstream object. Here is my code:

1
2
3
4
5
6
7
8
9
10
11
char* File::readln(int i)
{
	if (i >= 1 && isOpen()) {
		char value[i+1];
		if (stream->good())
			stream->getline(value, i); // <---- segfault here
		return value;
	}

	return NULL;
}


I've created a wrapper class called 'File' to help me with io operations. I've created a new fstream object called stream within the File class. the 'isOpen()' function called the is_open() on the stream object (can also checks to make sure stream is not NULL).

i have a default parameter value assigned to it (256). The code that calls my readln(..) function looks like this:
1
2
char* result;
result = file->readln();


Does anyone have any idea why I would be getting a segfault error??

Thanks for any help guys!

Jarrett
Debuggers cannot be as exact as we take them at face value, simply because of the way the processor caches instructions and the like.

Chances are that you are segfaulting on the next line, when you try to return a local value.

You need to do it thus:

1
2
3
4
5
6
7
8
9
10
char* File::readln(int i)
{
	if (i >= 1 && isOpen() && stream->good())
	{
		char* result = new char [i+1];
		stream->getline(result, i);
		return result;
	}
	return NULL;
}

Also, please be careful with your brace style. You've got two different ones going there. Pick one and stick to it.

(Please note that I changed the way your function works. Your original returns non-NULL if the file is open, even if the file is not good(). The version here only returns non-NULL if everything went correctly. If you meant the previous, but odd, behavior, you'll need to change it back. The important thing was to properly allocate memory to return.)

Of course, now that you are properly allocating memory to return, you must deallocate it when you are done with it.

1
2
3
4
5
6
7
8
9
char* s;
s = file->readln();
if (s)
  {
  /* Do something with s here */
  ...
  // Don't forget to free the memory when you are done with it!
  delete [] s;
  }

Hope this helps.
Hi duoas, thanks for that awesome reply!

I did as you suggested, and it seemed to work, but I got a segfault at a different section. I decided to comment out all of the code I'm using for io operations to try to pinpoint the segfault, but now something crazy is happening! I recompiled after commenting out the io code, but I'm still getting the segfault..which isn't really wierd, however, the segfault stack trace goes through the io code I commented out! It looks like my application is calling code that shouldn't even be there, because it's commented out, but it's still being executed! I even deleted some of the io code, recompiled, and it's STILL being called!

I'm totally lost. any ideas? :D

Looks like I'm going to be doing some serious googling..

Thanks

Jarrett
Duoas wrote:
Also, please be careful with your brace style. You've got two different ones going there. Pick one and stick to it

That's called K&R style or 1TBS (One-true-brace-style). Braces for functions go on the next line, but braces for (pretty much) everything else go on the same line: http://en.wikipedia.org/wiki/Indent_style#K.26R_style
It's also the style used in the Linux kernel, and the style that I use.
Last edited on
Oops! Of course it is. :-\

In any case, K&R's brace style is confusing to beginners, and I do not recommend it.
This always happened to me, and its simply going past the end of the array or vector or list size. If you added char[i+1]; its going to go past even the end of the array. Try start at 1 and count char[i-1] - that way it will terminate at the end of the array and reference from the beginning if you add the for loop on the array. Alternatively write a character iterator, and store the chars in a vector<char> c; and don't get past the end by going != c.end();


hey all,

Thanks again for the advice. Personally, I prefer K&R, but I'm also used to using Java, and C++ is new territory for me. So I will take your advice duoas.

CrayonBlaster, I'm not really sure what you mean, as I'm not iterating through the array, I'm just sending it to getline(..). But I take your point, assuming I was iterating through the array.

It turns out I forgot that I changed my compiled binary file to have the .exe extension, so all of my changes in the past few hours weren't showing up, and I was ready to pull my hair out haha. Anyway, I've corrected it now, and with your changes duoas it's purring like a kitten.

Thanks guys!

Cheers
Jarrett
Topic archived. No new replies allowed.