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?
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)