LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-08-2010, 09:03 PM   #1
greatcz
LQ Newbie
 
Registered: Jul 2010
Posts: 8

Rep: Reputation: 0
Unhappy A segmentation fault


The first time I used this readline function, it worked without trouble. But after I used fseek, it would cause a segmentation fault. How can I solve this problem? Thanks.


static char* readline(FILE *input)
{
int len;

if(fgets(line,max_line_len,input) == NULL)
return NULL;

while(strrchr(line,'\n') == NULL)
{
max_line_len *= 2;
line = (char *) realloc(line,max_line_len);
len = (int) strlen(line);
if(fgets(line+len,max_line_len-len,input) == NULL)
break;
}
return line;
}

int main(int argc, char** argv)
{
FILE *testFile, *model;
testFile = fopen(argv[1],"r");
model = fopen(argv[2],"r");
int nr_test_points=0, nr_attr=0;


if(testFile == NULL)
{
fprintf(stderr,"can't open input file %s\n",argv[1]);
exit(1);
}

max_line_len=1024;
line = (char *)malloc(max_line_len*sizeof(char));

while((line=readline(testFile))!=NULL)
{
nr_test_points++;
int temp = maxAttribute(line);
if(nr_attr < temp)
nr_attr = temp;
}


fseek(testFile, 0, SEEK_SET);


readline(testFile);//this line will cause the trouble
}
 
Old 07-08-2010, 11:12 PM   #2
Aquarius_Girl
Senior Member
 
Registered: Dec 2008
Posts: 4,731
Blog Entries: 29

Rep: Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940
Since you have not used Code tags, it is difficult to read your code.

Still you can study the following links to help yourself.
http://www.unknownroad.com/rtfm/gdbtut/gdbtoc.html
http://www.unknownroad.com/rtfm/gdbt...e.html#COMPILE
 
Old 07-09-2010, 12:51 AM   #3
zirias
Member
 
Registered: Jun 2010
Posts: 361

Rep: Reputation: 59
Right, in short, to debug a segfault, it is enough to compile with debugging symbols (gcc -O0 -g3 ...) and run the resulting executable in gdb (gdb /path/to/your/binary). It will break into the debugger when the segfault happens. Then you can type commands like 'bt' to get the backtrace of invoked functions or 'p x' to print the content of variable x.

In case the segfault does NOT happen that way, leave out the -O0 option when compiling. This is rare, but sometimes the segfault only gets triggered with applied compiler optimizations.

If you don't find the error yourself, post
- the code in [code]-tags, so it is readable,
- the relevant gdb output
 
Old 07-09-2010, 03:10 AM   #4
greatcz
LQ Newbie
 
Registered: Jul 2010
Posts: 8

Original Poster
Rep: Reputation: 0
Thanks for your advice. I have found the position of that segfault, but I don't know how to fix it. After using function fseek, I read the file again, and then it would cause a segfault.

Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <iostream>
using namespace std;


static int max_line_len;
static char *line = NULL;



static char* readline(FILE *input)
{
	int len;
	
	if(fgets(line,max_line_len,input) == NULL)
		return NULL;

	while(strrchr(line,'\n') == NULL)
	{
		max_line_len *= 2;
		line = (char *) realloc(line,max_line_len);
		len = (int) strlen(line);
		if(fgets(line+len,max_line_len-len,input) == NULL)
			break;
	}
	return line;
}

int maxAttribute(char *line)
{
	int maxAttri=0;
	int len=strlen(line);
	char *end=strrchr(line, ':');
	int sublen=strlen(end);
	int offset=len-sublen;
	while(line[--offset]!=' ');
	for(int i=offset+1; i<len-sublen; ++i)
		maxAttri=10*maxAttri+line[i]-48;
	return maxAttri;
}

int main(int argc, char** argv)
{
	FILE *testFile, *model;
	testFile = fopen(argv[1],"r");
	model = fopen(argv[2],"r");
	int nr_test_points=0, nr_attr=0;
	
	
	if(testFile == NULL)
	{
		fprintf(stderr,"can't open input file %s\n",argv[1]);
		exit(1);
	}
	
	max_line_len=1024;
	line = (char *)malloc(max_line_len*sizeof(char));
	
	
	while((line=readline(testFile))!=NULL)
	{
		nr_test_points++;
		int temp =  maxAttribute(line);
		if(nr_attr < temp)
			nr_attr = temp;
	}
	
	
	fseek(testFile, 0, SEEK_SET);
	
	
	readline(testFile);//segfault
	const int testArraySize = nr_attr * nr_test_points;	
	float *testArray = new float[ testArraySize ];
	
	//arrayInit(testArray, testArraySize, nr_attr, testFile);
	
	for(int i=0; i<13; ++i)
		cout<<testArray[i]<<' ';
				
}
 
Old 07-09-2010, 03:28 AM   #5
Aquarius_Girl
Senior Member
 
Registered: Dec 2008
Posts: 4,731
Blog Entries: 29

Rep: Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940
Did you run Gdb like this: (assuming your file name is jk.cpp)
Code:
anisha@linux-uitj:~/junk> g++ -g jk.cpp
anisha@linux-uitj:~/junk> gdb a.out
(gdb) b readline
Breakpoint 1 at 0x400b90: file jk.cpp, line 19.
(gdb) r
 
Old 07-09-2010, 10:07 AM   #6
greatcz
LQ Newbie
 
Registered: Jul 2010
Posts: 8

Original Poster
Rep: Reputation: 0
I ran Gdb like this.(heart_scale is a test file)
Code:
cz@cz-laptop:~/cuSvm$ gdb cuSvm 
GNU gdb (GDB) 7.1-ubuntu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/cz/cuSvm/cuSvm...(no debugging symbols found)...done.
(gdb) run heart_scale
Starting program: /home/cz/cuSvm/cuSvm heart_scale

Program received signal SIGSEGV, Segmentation fault.
0x002c62a3 in _IO_getline_info () from /lib/tls/i686/cmov/libc.so.6
(gdb) backtrace 
#0  0x002c62a3 in _IO_getline_info () from /lib/tls/i686/cmov/libc.so.6
#1  0x002c61d1 in _IO_getline () from /lib/tls/i686/cmov/libc.so.6
#2  0x002c521a in fgets () from /lib/tls/i686/cmov/libc.so.6
#3  0x08048a46 in readline(_IO_FILE*) ()
#4  0x08048d99 in main ()
 
Old 07-09-2010, 08:56 PM   #7
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
Did your call to fseek() succeed?
What is the value of max_line_len? Your statement max_line_len *= 2; will surely cause an overflow at some point...
 
Old 07-09-2010, 09:57 PM   #8
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,240

Rep: Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322
Quote:
Originally Posted by graemef View Post
Did your call to fseek() succeed?
Good point.

You really should be checking fseek's return value and writing the appropriate error-handling code.

Quote:
What is the value of max_line_len? Your statement max_line_len *= 2; will surely cause an overflow at some point...
Another good point. You're doubling the size of the buffer with each character read. Are you aware of how fast your memory usage is going to grow? Changing that would also allow you to change the condition in the fgets call, which is too complex to verify as it is.

Last edited by dugan; 07-09-2010 at 10:12 PM.
 
Old 07-09-2010, 11:10 PM   #9
greatcz
LQ Newbie
 
Registered: Jul 2010
Posts: 8

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by graemef View Post
Did your call to fseek() succeed?
What is the value of max_line_len? Your statement max_line_len *= 2; will surely cause an overflow at some point...
I used ftell to make sure that the call to fseek did succeed. And the value of max_line_len is 1024.

Quote:
Are you aware of how fast your memory usage is going to grow?
Actually, these codes are not mine. I just planned to do some modifications on some parts of other people's program. I just think it works on other people's program, so if I don't change it, it will cause me no trouble as well. Moreover I am not good at programming although I am trying to learn it.
How can I fix this problem?
 
Old 07-10-2010, 12:08 AM   #10
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
I don't know what would happen with your code at the end of the file where there is no new line character. Do you enter that while loop and if so does max_line_len get incremented.

Don't Assume that it works just because you got it from someone else. They may not have tested it with your conditions (fseek to rewind the file). You can quickly test the value by using printf() statements.
 
Old 07-10-2010, 01:03 AM   #11
greatcz
LQ Newbie
 
Registered: Jul 2010
Posts: 8

Original Poster
Rep: Reputation: 0
Quote:
Do you enter that while loop and if so does max_line_len get incremented.
I have tried to delete the while loop which means max_line_len remains the same length, but segfault still occured. It seems that it is not an overflow problem.

And return value of the call to fseek is 0.
 
Old 07-10-2010, 01:22 AM   #12
greatcz
LQ Newbie
 
Registered: Jul 2010
Posts: 8

Original Poster
Rep: Reputation: 0
I have found the problem.
After reading the whole file, the memory of line is reclaimed.
So I just need to reallocate the memory again.
Thank you for your help and time. I really appreciate it.
 
Old 07-10-2010, 05:34 AM   #13
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by greatcz View Post
while((line=readline(testFile))!=NULL)
}
I missed that little detail the first time I read your code.

Quote:
Originally Posted by greatcz View Post
I have found the problem.
After reading the whole file, the memory of line is reclaimed.
So I just need to reallocate the memory again.
The memory is not reclaimed. The pointer to the memory is lost. So if you allocate the memory again, you'll have a minor memory leak. That isn't serious in this project but it is a bad habit to get into.

Your code doesn't seem to have any reason to assign the result of readline to line (either readline returns line and the assignment does nothing or readline returns 0 and the assignment does harm). So you could just change it to:

while(readline(testFile)!=NULL)

Last edited by johnsfine; 07-10-2010 at 05:39 AM.
 
Old 07-11-2010, 12:57 AM   #14
greatcz
LQ Newbie
 
Registered: Jul 2010
Posts: 8

Original Poster
Rep: Reputation: 0
Thank you for your advice.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Segmentation Fault zkhuhr Programming 2 08-21-2008 06:34 AM
yast segmentation fault, system freezing - nvidia driver at fault? BaltikaTroika SUSE / openSUSE 2 12-02-2005 09:34 AM
Segmentation fault with ls -l Sledge Fedora 8 03-29-2005 08:02 PM
segmentation fault for everything gsv Linux - Newbie 1 08-23-2004 06:19 PM
Segmentation Fault XPediTioN Slackware 2 09-18-2003 08:16 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:54 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration