我开始学习 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] = '\0';
k++;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我想在用户不输入 '\n' 时阅读,但它可以工作 2x 然后我得到这个错误 realloc(): invalid next size: 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 字节 alloc'd
==7662==在 0x4C27C0F: malloc (vg_replace_malloc.c:299)
==7662== by 0x400847: readFraze() (main.c:25)
==7662== by 0x400818: main (main.c:15)
==7662==
==7662== 条件跳转或移动取决于未初始化的值 ==7662== by 0x400818: main (main.c:15)
==7662== 在 0x56BFCA2: getdelim (iogetdelim.c:63)
==7662== by 0x40093E: readFraze() (main.c:44)
谁能告诉我,我做错了什么?
当您看到涉及malloc、realloc或的回溯时free,这意味着您的堆已损坏:您的程序覆盖了内存管理系统使用的一些数据结构。最常见的原因是写入超出了分配的块的边界malloc(缓冲区溢出)并继续使用malloc调用后分配的内存块free(释放后使用)。
正如Weather Vane在评论中已经提到的那样,您传递给malloc和reallocfor的大小s与您对s. s是一个指向 的数组的指针struct fraze,并且您最多使用k该数组的元素,因此内存块必须足够大以容纳k+1类型为 的元素struct fraze。鉴于您的分配策略,这意味着您必须i为 type 元素留出空间struct fraze。但是您的实际分配仅用于sizeof( int )字节,这还不够。
做那个
s = malloc(i * sizeof(*s));
Run Code Online (Sandbox Code Playgroud)
和(带错误检查)
s_FRAZE *new_s = realloc(s, i * sizeof(*s));
if (new_s == NULL) {
fputs("Out of memory!\n", stderr);
exit(2);
}
s = new_s;
Run Code Online (Sandbox Code Playgroud)
一般来说i,您将指针分配到的元素数组的大小s是i * sizeof(*s). 不要使用 sizeof(
TYPE )