问题
I started learning about struct in C. Today I found a problem, that I can't solve. I have this code:
typedef struct fraze
{
char *mostSearch = NULL; // for string from user
double freq;
} s_FRAZE;
int readFraze( )
{
int i = 2, k;
size_t len = 0;
char c;
s_FRAZE *s;
s = (s_FRAZE *)malloc( i * sizeof( int ));
k = 0;
while( (c = getchar()) != '\n')
{
ungetc( c, stdin );
if( scanf( "%lf%c", &s[k].freq, &c) != 2 || c != ':' )
{
return 1;
}
if( k + 1 >= i )
{
i *= 2;
printf("%d\n", i );
s = (s_FRAZE *)realloc( s, i * sizeof( int ));
}
len = getline(&s[k].mostSearch, &len, stdin );
s[k].mostSearch[len-1] = '\0';
k++;
}
return 0;
}
I want to read while user don't type '\n', but it works 2x and then I get this erorr realloc(): invalid next size: 0x0000000001559010 *** I tryed use valgrind and there are more errors:
==7662== Invalid write of size 8
==7662== at 0x56AEBB4: _IO_vfscanf (vfscanf.c:2328)
==7662== by 0x56BBD3A: scanf (scanf.c:33)
==7662== by 0x40089F: readFraze() (main.c:31)
==7662== by 0x400818: main (main.c:15)
==7662== Address 0x59fe048 is 0 bytes after a block of size 8 alloc'd
==7662== at 0x4C27C0F: malloc (vg_replace_malloc.c:299)
==7662== by 0x400847: readFraze() (main.c:25)
==7662== by 0x400818: main (main.c:15)
==7662==
==7662== Conditional jump or move depends on uninitialised value(s)
==7662== at 0x56BFCA2: getdelim (iogetdelim.c:63)
==7662== by 0x40093E: readFraze() (main.c:44)
==7662== by 0x400818: main (main.c:15)
Can anyone tell me, what am I doing wrong?
回答1:
When you see a backtrace involving malloc, realloc or free, it means your heap is corrupted: your program overwrote some data structures used by the memory management system. The most common causes for that are writing past the bounds of a block allocated by malloc (buffer overflow) and continuing to use a memory block allocated by malloc after calling free on it (use after free).
As Weather Vane already mentioned in a comment, the size you pass to malloc and realloc for s doesn't match your usage of s. s is a pointer to an array of struct fraze, and you use elements up to k of this array, so the memory block must be large enough for k+1 elements of type struct fraze. Given your allocation policy, that means you must leave room for i elements of type struct fraze. But your actual allocation is for only sizeof( int ) bytes, which is not enough.
Make that
s = malloc(i * sizeof(*s));
and (with error checking)
s_FRAZE *new_s = realloc(s, i * sizeof(*s));
if (new_s == NULL) {
fputs("Out of memory!\n", stderr);
exit(2);
}
s = new_s;
Generally speaking, the size of an array of i elements that you're assigning the pointer s to is i * sizeof(*s). Don't use sizeof(
TYPE)
来源:https://stackoverflow.com/questions/34254307/realloc-invalid-next-size-realloc-dynamic-struct