realloc(): 下一个大小无效 - realloc 动态结构
realloc(): invalid next size - realloc dynamic struct
我开始学习C中的struct。今天我发现了一个问题,我无法解决。我有这个代码:
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] = '[=10=]';
k++;
}
return 0;
}
我想在用户不输入“\n”时阅读,但它工作了 2 倍,然后我得到这个错误 realloc():下一个大小无效:0x0000000001559010 ***
我尝试使用 valgrind,但出现了更多错误:
==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)
谁能告诉我,我做错了什么?
当您看到涉及 malloc
、realloc
或 free
的回溯时,这意味着您的堆已损坏:您的程序覆盖了内存管理系统使用的一些数据结构。最常见的原因是写入越过 malloc
分配的块的边界(缓冲区溢出)并在调用 free
后继续使用 malloc
分配的内存块(使用免费后)。
正如评论中已经提到的 Weather Vane,您为 s
传递给 malloc
和 realloc
的大小与您对 [=20= 的使用不匹配]. s
是一个指向 struct fraze
数组的指针,而你最多使用这个数组的 k
个元素,因此内存块必须足够大以容纳 k+1
个类型的元素struct fraze
。根据您的分配策略,这意味着您必须为类型 struct fraze
的 i
个元素留出空间。但是您的实际分配仅为 sizeof( int )
字节,这还不够。
做到这一点
s = malloc(i * sizeof(*s));
和(带错误检查)
s_FRAZE *new_s = realloc(s, i * sizeof(*s));
if (new_s == NULL) {
fputs("Out of memory!\n", stderr);
exit(2);
}
s = new_s;
一般来说,您要将指针 s
分配给的 i
个元素数组的大小是 i * sizeof(*s)
。不要使用 sizeof(
类型)
我开始学习C中的struct。今天我发现了一个问题,我无法解决。我有这个代码:
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] = '[=10=]';
k++;
}
return 0;
}
我想在用户不输入“\n”时阅读,但它工作了 2 倍,然后我得到这个错误 realloc():下一个大小无效:0x0000000001559010 *** 我尝试使用 valgrind,但出现了更多错误:
==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)
谁能告诉我,我做错了什么?
当您看到涉及 malloc
、realloc
或 free
的回溯时,这意味着您的堆已损坏:您的程序覆盖了内存管理系统使用的一些数据结构。最常见的原因是写入越过 malloc
分配的块的边界(缓冲区溢出)并在调用 free
后继续使用 malloc
分配的内存块(使用免费后)。
正如评论中已经提到的 Weather Vane,您为 s
传递给 malloc
和 realloc
的大小与您对 [=20= 的使用不匹配]. s
是一个指向 struct fraze
数组的指针,而你最多使用这个数组的 k
个元素,因此内存块必须足够大以容纳 k+1
个类型的元素struct fraze
。根据您的分配策略,这意味着您必须为类型 struct fraze
的 i
个元素留出空间。但是您的实际分配仅为 sizeof( int )
字节,这还不够。
做到这一点
s = malloc(i * sizeof(*s));
和(带错误检查)
s_FRAZE *new_s = realloc(s, i * sizeof(*s));
if (new_s == NULL) {
fputs("Out of memory!\n", stderr);
exit(2);
}
s = new_s;
一般来说,您要将指针 s
分配给的 i
个元素数组的大小是 i * sizeof(*s)
。不要使用 sizeof(
类型)