FCLOSE()导致段故障
-
22-07-2019 - |
题
我有我解析制表符分隔的文本文件。它的第一列包含格式chrX
,其中X
表示一组串,例如,“1”,“2”,...,“X”,“Y”的字符串。
这些各自存储在一个名为char*
chromosome
,作为文件被解析。
在文本文件上的第一列进行排序字典顺序,即,我将具有多个从开始“CHR1”的行,然后在“CHR2”等。
在每个“chrX”项,我需要打开与此相关的条目的另一个文件:
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);
我知道我不是过客fclose
NULL指针,因为直到分段错误,我从这个文件中读取数据。我甚至可以把这个包在一个条件,我仍然得到了错误:
if (merbaseIn != NULL) {
fclose(merbaseIn);
}
此外,我知道openSourceFile
作品(至少对于chr1
,设置当FILE*
的第一文件句柄),因为我的应用程序解析chr1
行和从正确FILE*
源文件中读取数据。
这是关于这个fclose
调用导致分段错误发生?
解决方案
valgrind --db-attach=yes --leak-check=yes --tool=memcheck --num-callers=16 --leak-resolution=high ./yourprogram args
这是非常有可能的段错误是在堆上,没有任何影响真实当地人内存损坏引起的。 Valgrind的会马上告诉你第一个错误的访问你做。
编辑:--db-attach
选项valgrind
因为在2014年发布3.10.0已弃用发行说明状态:
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
其他提示
一个错误我注意到是此行:
*chrome = (char *) malloc ((size_t) strlen(field));
这应该是:
*chrome = (char *) malloc ((size_t) strlen(field)+1);
这是因为串具有在端部的闭合0,这还必须以腾出空间给
最佳的猜测是,代码的一些其他部分是通过一个缓冲区溢出或类似错误腐败存储器。
虽然不太可能的原因,你当完整的文件名超过100个字符有潜在的溢出情况在你的文件名数组。
我建议使用调试器来观看由merbaseIn变量用于在存储器位置的变化。
通用指针问题
C是一种伟大的语言,但它需要你不揍你自己的记忆。除了问题先前指出其中的malloc是1个字节短,则可以具有其他的指针的问题。
我建议使用存储器调试器。在过去,电子围栏是相当受欢迎,但这些天我的听到更多的valgrind 。有很多其它的选择。
为什么这个文件** filePtr如果只有这个FILE * filePtr就足够了? 只是一个想法...
valgrind
与memcheck
肯定是发现分割故障原因的合适的工具。使用具有valgrind
调试器,请注意--db-attach
选项valgrind
已经废弃了,因为Valgrind的3.10.0在2014年发行的发行说明状态:
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
查看每次你使用的 “的malloc”的地方,看看你犯了一个错误。
例如,我把从文件读入一个char **行,但不正确地 malloced它为:
my_list = malloc(sizeof(char) * num_lines_found_in_file);
当它应该是:
my_list = malloc(sizeof(char*)* num_lines_found_in_file);