ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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.
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
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]<<' ';
}
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 ()
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.
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?
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.
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.
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.
I missed that little detail the first time I read your code.
Quote:
Originally Posted by greatcz
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:
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.