Использование realloc для расширения буфера при чтении из файла приводит к сбою

Я пишу код, который должен читать fasta файлы, поэтому часть моего кода (включенного ниже) является парсером fasta. Поскольку одна последовательность может занимать несколько строк в формате fasta, мне нужно объединить несколько последовательных строк, считанных из файла, в одну строку. Я делаю это, перераспределяя буфер строки после чтения каждой строки, чтобы его длина была равна текущей длине последовательности плюс длина прочитанной строки. Я делаю некоторые другие вещи, например, удаляю пробелы и т.д. Все идет хорошо для первой последовательности, но файлы fasta могут содержать несколько последовательностей. Аналогично, у меня есть динамический массив структур с двумя строками (название и фактическая последовательность), представляющими собой "char *". Опять же, когда я встречаю новое название (введенное строкой, начинающейся с '>'), я увеличиваю количество последовательностей и перераспределяю буфер списка последовательностей. При выделении места для второй последовательности с

*** glibc detected *** ./stackoverflow: malloc(): memory corruption: 0x09fd9210 ***
Aborted

realloc происходит сбой, но я не могу понять почему. Я прогнал его через gdb, и все вроде бы работает (т.е. все инициализируется, значения кажутся вменяемыми)... Вот код:

#include 
#include 
#include 
#include 
#include 
#include 

//a struture to keep a record of sequences read in from file, and their titles
typedef struct {
    char *title;
    char *sequence;
} sequence_rec;

//string convenience functions

//checks whether a string consists entirely of white space
int empty(const char *s) {
    int i;
    i = 0;
    while (s[i] != 0) {
        if (!isspace(s[i])) return 0;
        i++;
    }
    return 1;
}

//substr allocates and returns a new string which is a substring of s from i to
//j exclusive, where i < j; If i or j are negative they refer to distance from
//the end of the s
char *substr(const char *s, int i, int j) {
    char *ret;
    if (i < 0) i = strlen(s)-i;
    if (j < 0) j = strlen(s)-j;
    ret = malloc(j-i+1);
    strncpy(ret,s,j-i);
    return ret;
}

//strips white space from either end of the string
void strip(char **s) {
    int i, j, len;
    char *tmp = *s;
    len = strlen(*s);
    i = 0;
    while ((isspace(*(*s+i)))&&(i < len)) {
        i++;
    }
    j = strlen(*s)-1;
    while ((isspace(*(*s+j)))&&(j > 0)) {
        j--;
    }
    *s = strndup(*s+i, j-i);
    free(tmp);
}


int main(int argc, char**argv) {
    sequence_rec *sequences = NULL;
    FILE *f = NULL;
    char *line = NULL;
    size_t linelen;
    int rcount;
    int numsequences = 0;

    f = fopen(argv[1], "r");
    if (f == NULL) {
        fprintf(stderr, "Error opening %s: %s\n", argv[1], strerror(errno));
        return EXIT_FAILURE;
    }
    rcount = getline(&line, &linelen, f);
    while (rcount != -1) {
        while (empty(line)) rcount = getline(&line, &linelen, f);
        if (line[0] != '>') {
            fprintf(stderr,"Sequence input not in valid fasta format\n");
            return EXIT_FAILURE;
        }

        numsequences++;
        sequences = realloc(sequences,sizeof(sequence_rec)*numsequences);
        sequences[numsequences-1].title = strdup(line+1); strip(&sequences[numsequences-1].title);
        rcount = getline(&line, &linelen, f);
        sequences[numsequences-1].sequence = malloc(1); sequences[numsequences-1].sequence[0] = 0;
        while ((!empty(line))&&(line[0] != '>')) {
            strip(&line);
            sequences[numsequences-1].sequence = realloc(sequences[numsequences-1].sequence, strlen(sequences[numsequences-1].sequence)+strlen(line)+1);
            strcat(sequences[numsequences-1].sequence,line);
            rcount = getline(&line, &linelen, f);
        }
    }
    return EXIT_SUCCESS;
}

5
задан sirlark 23 January 2012 в 14:26
поделиться