我正在解析以制表符分隔的文本文件。其第一列包含格式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*
调用有什么用?
答案 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)
答案 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);