3

我有一个正在解析的制表符分隔的文本文件。它的第一列包含格式为 的字符串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);                                                                                                                                                         
    }                                                                                                                                                                             
}      

问题是我的应用程序在以下行退出时出现从第一个染色体到第二个染色体(从chr1chr2)的分段错误,我关闭了我打开的第一个染色体文件:

fclose(merbaseIn);

我知道我没有传递fcloseNULL 指针,因为直到出现分段错误,我才从这个文件中读取数据。我什至可以将它包装在一个条件中,但我仍然得到错误:

if (merbaseIn != NULL) {
    fclose(merbaseIn);
}

此外,我知道openSourceFile有效(至少对于chr1,在设置 的第一个文件句柄时FILE*),因为我的应用程序解析行并正确地从源文件chr1中读取数据。FILE*

这个fclose调用导致分段错误发生的原因是什么?

4

8 回答 8

9
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

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

于 2009-09-18T08:16:09.653 回答
5

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

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

应该是:

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

这是因为字符串末尾有一个结束 0,您还必须为它腾出空间

于 2009-09-18T08:15:26.750 回答
1

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

虽然不太可能是原因,但当完整文件名超过 100 个字符时,文件名数组中可能会出现溢出情况。

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

于 2009-09-18T08:20:17.203 回答
1

通用指针问题

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

我建议使用内存调试器。过去,Electric Fence相当流行,但这些天我听到更多关于 valgrind 的信息。还有很多其他的选择。

于 2009-09-18T08:23:45.670 回答
1

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

free(chromosome);

后面应该是:

chromosome = NULL;

为了防止可能使用不再有效的值。

于 2009-09-18T08:34:29.343 回答
0

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

于 2009-10-21T14:58:43.587 回答
0

valgrindwithmemcheck绝对是发现分段错误原因的正确工具。要使用带有 的调试器valgrind,请注意,自 2014 年发布 Valgrind 3.10.0 以来,该--db-attach选项已被弃用。发行说明指出:valgrind

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

于 2017-07-03T01:38:01.040 回答
0

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

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

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

什么时候应该是:

my_list = malloc(sizeof(char*)* num_lines_found_in_file);
于 2019-03-14T22:12:31.993 回答