Вопрос

У меня есть текстовый файл с разделителями табуляции, который я анализирую. Его первый столбец содержит строки в формате 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 устарел с момента выпуска 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

Другие советы

одна ошибка, которую я замечаю, это строка:

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

который должен быть:

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

Это потому, что строка имеет закрывающий 0 в конце, который вы также должны освободить место для

Лучше всего предположить, что какая-то другая часть вашего кода повреждает память из-за переполнения буфера или подобной ошибки.

Хотя это вряд ли является причиной, у вас есть потенциальное переполнение в массиве имен файлов, когда полное имя файла превышает 100 символов.

Я бы предложил использовать отладчик для отслеживания изменений в ячейке памяти, используемой переменной merbaseIn.

Общая проблема с указателями

C - отличный язык, но он требует, чтобы вы не забивали свою собственную память. Помимо ранее отмеченной проблемы, когда malloc имеет длину 1 байт, у вас могут быть и другие проблемы с указателями.

Я бы предложил использовать отладчик памяти . В прошлом Электрический забор был довольно популярен, но в эти дни я узнать больше о valgrind . Есть много других вариантов.

Помимо ошибки, найденной reinier , я подозреваю, что:

free(chromosome);

должно сопровождаться:

chromosome = NULL;

для предотвращения возможного использования недействительного значения.

почему этот FILE ** 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 " и посмотрите, не ошиблись ли вы.

Например, я помещал строки, прочитанные из файла, в символ **, но я неправильно называет это как:

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

Когда это должно было быть:

my_list = malloc(sizeof(char*)* num_lines_found_in_file);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top