我开始在C学习结构。今天我发现了一个问题,我无法解决。我有这段代码:
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;
}
我想在用户不输入'\ n'时读取,但它工作2x然后我得到这个erorr realloc():下一个大小无效:0x0000000001559010 *** 我尝试使用valgrind,还有更多错误:
== 7662 ==写入大小为8的无效 == 7662 ==在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 ==地址0x59fe048是大小为8的块后的0字节 == 7662 ==在0x4C27C0F:malloc(vg_replace_malloc.c:299)
== 7662 == by 0x400847:readFraze()(main.c:25)
== 7662 == by 0x400818:main(main.c:15)
== == 7662
== 7662 ==有条件的跳跃或移动取决于未初始化的值(s)
== 7662 ==在0x56BFCA2:getdelim(iogetdelim.c:63)
== 7662 == by 0x40093E:readFraze()(main.c:44)
== 7662 == by 0x400818:main(main.c:15)
谁能告诉我,我做错了什么?
答案 0 :(得分:3)
当您看到涉及malloc
,realloc
或free
的回溯时,表示您的堆已损坏:您的程序覆盖了内存管理系统使用的某些数据结构。最常见的原因是写入malloc
分配的块的边界(缓冲区溢出)并在调用malloc
之后继续使用由free
分配的内存块(使用免费之后)。
在评论中已经提及Weather Vane时,您传递给malloc
的{{1}}和realloc
s
的尺寸与您s
的使用不符。 s
是指向struct fraze
数组的指针,并且您使用此数组的k
元素,因此内存块必须足够大,以便k+1
类型的元素struct fraze
。根据您的分配政策,这意味着您必须为类型i
的{{1}}元素留出空间。但是你的实际分配只是struct fraze
个字节,这还不够。
制作
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;
指针的i
元素数组的大小为s
。不要使用sizeof(
TYPE )