fclose()导致分段错误

时间:2009-09-18 08:09:51

标签: c segmentation-fault fopen fclose

我正在解析以制表符分隔的文本文件。其第一列包含格式chrX的字符串,其中X表示一组字符串,例如“1”,“2”,......,“X”,“Y”。

这些都存储在名为char*的{​​{1}}中,因为文件已被解析。

文本文件按字典顺序排在第一列,即我将有一些以“chr1”开头的行,然后是“chr2”等。

在每个“chrX”条目中,我需要打开与此条目相关联的另一个文件:

chromosome

我的函数FILE *merbaseIn; // loop through rows... if (chromosome == NULL) openSourceFile(&chromosome, fieldArray[i], &merbaseIn, GENPATHIN); else { if (strcmp(chromosome, fieldArray[i]) != 0) { // new chromosome fclose(merbaseIn); // close old chromosome FILE ptr free(chromosome); // free old chromosome ptr openSourceFile(&chromosome, fieldArray[i], &merbaseIn, GENPATHIN); // set up new chromosome FILE ptr } } // parse row 定义如下:

openSourceFile

问题是我的应用程序在下一行从第一个染色体到第二个染色体(从void openSourceFile (char** chrome, const char* field, FILE** filePtr, const char *path) { char filename[100]; *chrome = (char *) malloc ((size_t) strlen(field)); if (*chrome == NULL) { fprintf(stderr, "ERROR: Cannot allocate memory for chromosome name!"); exit(EXIT_FAILURE); } strcpy(*chrome, field); sprintf(filename,"%s%s.fa", path, field); *filePtr = fopen(filename, "r"); if (*filePtr == NULL) { fprintf(stderr, "ERROR: Could not open fasta source file %s\n", filename); exit(EXIT_FAILURE); } } chr1)退出分段错误,在那里我关闭了我的第一个染色体文件打开:

chr2

我知道我没有传递fclose(merbaseIn); 一个NULL指针,因为直到分段错误,我正在读取此文件中的数据。我甚至可以将它包装在条件中,我仍然得到错误:

fclose

此外,我知道if (merbaseIn != NULL) { fclose(merbaseIn); } 在设置openSourceFile的第一个文件句柄时起作用(至少对chr1有效)因为我的应用程序解析FILE*行并读取数据正确地从chr1源文件。

导致发生分段错误的FILE*调用有什么用?

8 个答案:

答案 0 :(得分:8)

valgrind --db-attach=yes --leak-check=yes --tool=memcheck --num-callers=16 --leak-resolution=high ./yourprogram args

段错误很可能是由堆上的内存损坏引起的,而不是影响本地的任何内容。 Valgrind会立即显示您第一次错误访问。

编辑:自2014年版本3.10.0以来,--db-attach valgrind的{​​{1}}选项已弃用。发行说明指出:

The built-in GDB server capabilities are superior and should be used
instead. Learn more here:

http://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver

答案 1 :(得分:5)

我注意到的一个错误是这一行:

 *chrome = (char *) malloc ((size_t) strlen(field));

应该是:

 *chrome = (char *) malloc ((size_t) strlen(field)+1);

这是因为字符串末尾的结尾为0,您还必须为

腾出空间

答案 2 :(得分:1)

最好的猜测是,代码的其他部分是通过缓冲区溢出或类似错误来破坏内存。

虽然不太可能是原因,但是当完整文件名超过100个字符时,您的文件名数组中可能存在溢出条件。

我建议使用调试器来监视merbaseIn变量使用的内存位置的变化。

答案 3 :(得分:1)

通用指针问题

C是一种很棒的语言,但它确实要求你不要破坏自己的记忆。除了前面提到的malloc短1字节的问题,你可能还有其他指针问题。

我建议using a memory debugger。在过去,Electric Fence相当受欢迎,但这些天我hear more about valgrind。还有很多其他选择。

答案 4 :(得分:1)

reinier发现的错误外,我怀疑:

free(chromosome);

后面应该是:

chromosome = NULL;

以防止潜在使用不再有效的值。

答案 5 :(得分:0)

为什么这个FILE ** filePtr如果只有这个FILE * filePtr就足够了? 只是一个想法...

答案 6 :(得分:0)

带有valgrind

memcheck绝对是发现分段错误原因的正确工具。要将调试器与valgrind一起使用,请注意,自2014年Valgrind 3.10.0发布以来,--db-attach的{​​{1}}选项已被弃用。发行说明指出:

valgrind

http://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver

答案 7 :(得分:0)

查看您使用过的每个地方“ malloc” ,看看您是否做错了。

例如,我将从文件读取的行放入char **中,但是我错误地 将其分配为:

my_list = malloc(sizeof(char) * num_lines_found_in_file);

应该在什么时候出现:

my_list = malloc(sizeof(char*)* num_lines_found_in_file);