Tôi đang viết một số mã cần đọc fasta files, vì vậy một phần mã của tôi (bao gồm bên dưới) là trình phân tích cú pháp nhanh. Khi một chuỗi đơn có thể mở rộng nhiều dòng trong định dạng fasta, tôi cần phải nối nhiều dòng liên tiếp đọc từ tệp vào một chuỗi duy nhất. Tôi làm điều này, bằng cách realloc'ing chuỗi bộ đệm sau khi đọc tất cả các dòng, là chiều dài hiện tại của chuỗi cộng với độ dài của dòng đọc in Tôi làm một số công cụ khác, như tước không gian màu trắng vv Tất cả đều tốt cho chuỗi đầu tiên, nhưng các tệp fasta có thể chứa nhiều chuỗi. Vì vậy, tương tự, tôi có một mảng động của các cấu trúc với hai chuỗi (tiêu đề và chuỗi thực tế), là "char *". Một lần nữa, khi tôi gặp phải một tiêu đề mới (được giới thiệu bởi một dòng bắt đầu bằng '>'), tôi tăng số lượng các chuỗi, và thực hiện lại bộ đệm danh sách chuỗi. Các realloc segfaults trên phân bổ không gian cho chuỗi thứ hai vớiSử dụng realloc để mở rộng bộ đệm trong khi đọc từ tập tin treo
*** glibc detected *** ./stackoverflow: malloc(): memory corruption: 0x09fd9210 ***
Aborted
Đối với cuộc sống của tôi, tôi không thể thấy lý do tại sao. Tôi đã chạy nó thông qua gdb và mọi thứ dường như được làm việc (tức là tất cả mọi thứ được khởi tạo, các giá trị dường như lành mạnh) ... Dưới đây là các mã:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <errno.h>
//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;
}
Cảm ơn tất cả các nhận xét về thường trình chuỗi con. Tôi đã sửa nó trong mã của tôi. Tuy nhiên, tôi cũng nhận thấy rằng cách tôi xử lý các chỉ số tiêu cực là sai. Tôi nên thêm chỉ số âm, không trừ nó. Điều đó đang được nói, tôi cũng nhận ra rằng tôi đã sao chép hàm nền do lỗi, vì tôi không gọi nó trong phần còn lại của mã được dán. – sirlark
'strip()' cũng bị lỗi. Nó sẽ làm những điều xấu với các chuỗi có độ dài bằng không. Có vẻ như bạn không gọi nó bằng các chuỗi như vậy, nhưng tôi nghĩ rằng nó sẽ là một điều tốt để sửa chữa khi nó được sử dụng ở nơi khác. –