Note that there are some explanatory texts on larger screens.

plurals
  1. POUsing realloc to expand buffer while reading from file crashes
    primarykey
    data
    text
    <p>I am writing some code that needs to read <a href="http://en.wikipedia.org/wiki/FASTA_format" rel="noreferrer">fasta files</a>, so part of my code (included below) is a fasta parser. As a single sequence can span multiple lines in the fasta format, I need to concatenate multiple successive lines read from the file into a single string. I do this, by realloc'ing the string buffer after reading every line, to be the current length of the sequence plus the length of the line read in. I do some other stuff, like stripping white space etc. All goes well for the first sequence, but fasta files can contain multiple sequences. So similarly, I have a dynamic array of structs with a two strings (title, and actual sequence), being "char *". Again, as I encounter a new title (introduced by a line beginning with '>') I increment the number of sequences, and realloc the sequence list buffer. The realloc segfaults on allocating space for the second sequence with</p> <pre><code>*** glibc detected *** ./stackoverflow: malloc(): memory corruption: 0x09fd9210 *** Aborted </code></pre> <p>For the life of me I can't see why. I've run it through gdb and everything seems to be working (i.e. everything is initialised, the values seems sane)... Here's the code:</p> <pre><code>#include &lt;stdio.h&gt; #include &lt;string.h&gt; #include &lt;stdlib.h&gt; #include &lt;ctype.h&gt; #include &lt;math.h&gt; #include &lt;errno.h&gt; //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 &lt; 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 &lt; 0) i = strlen(s)-i; if (j &lt; 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)))&amp;&amp;(i &lt; len)) { i++; } j = strlen(*s)-1; while ((isspace(*(*s+j)))&amp;&amp;(j &gt; 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(&amp;line, &amp;linelen, f); while (rcount != -1) { while (empty(line)) rcount = getline(&amp;line, &amp;linelen, f); if (line[0] != '&gt;') { 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(&amp;sequences[numsequences-1].title); rcount = getline(&amp;line, &amp;linelen, f); sequences[numsequences-1].sequence = malloc(1); sequences[numsequences-1].sequence[0] = 0; while ((!empty(line))&amp;&amp;(line[0] != '&gt;')) { strip(&amp;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(&amp;line, &amp;linelen, f); } } return EXIT_SUCCESS; } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload