Ale*_*lds 3 c fopen segmentation-fault fclose
我有一个制表符分隔的文本文件,我正在解析.其第一列包含格式的字符串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
Run Code Online (Sandbox Code Playgroud)
我有一个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);
}
}
Run Code Online (Sandbox Code Playgroud)
问题是我的应用程序在下一行从第一个染色体到第二个染色体(从chr1到chr2)退出分段错误,在那里我关闭了我打开的第一个染色体文件:
fclose(merbaseIn);
Run Code Online (Sandbox Code Playgroud)
我知道我没有传递fcloseNULL指针,因为直到分段错误,我正在从这个文件中读取数据.我甚至可以在条件中包装它,我仍然得到错误:
if (merbaseIn != NULL) {
fclose(merbaseIn);
}
Run Code Online (Sandbox Code Playgroud)
此外,我知道openSourceFile工作(至少chr1在设置第一个文件句柄时FILE*),因为我的应用程序解析chr1行并FILE*正确地从源文件中读取数据.
这个fclose调用导致分段错误发生的原因是什么?
valgrind --db-attach=yes --leak-check=yes --tool=memcheck --num-callers=16 --leak-resolution=high ./yourprogram args
Run Code Online (Sandbox Code Playgroud)
segfault很可能是由堆上的内存损坏引起的,而不是任何影响本地的内存. Valgrind会立即向您显示您所犯的第一个错误访问权限.
编辑:自2014年版本3.10.0以来已弃用的--db-attach选项valgrind.发行说明指出:
The built-in GDB server capabilities are superior and should be used
instead. Learn more here:
Run Code Online (Sandbox Code Playgroud)
http://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver
我注意到的一个错误是这一行:
*chrome = (char *) malloc ((size_t) strlen(field));
Run Code Online (Sandbox Code Playgroud)
应该是:
*chrome = (char *) malloc ((size_t) strlen(field)+1);
Run Code Online (Sandbox Code Playgroud)
这是因为一个字符串在结尾处有一个结束0,你还必须腾出空间