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)

谁能告诉我,我做错了什么?

当您看到涉及 mallocreallocfree 的回溯时,这意味着您的堆已损坏:您的程序覆盖了内存管理系统使用的一些数据结构。最常见的原因是写入越过 malloc 分配的块的边界(缓冲区溢出)并在调用 free 后继续使用 malloc 分配的内存块(使用免费后)。

正如评论中已经提到的 Weather Vane,您为 s 传递给 mallocrealloc 的大小与您对 [=20= 的使用不匹配]. s 是一个指向 struct fraze 数组的指针,而你最多使用这个数组的 k 个元素,因此内存块必须足够大以容纳 k+1 个类型的元素struct fraze。根据您的分配策略,这意味着您必须为类型 struct frazei 个元素留出空间。但是您的实际分配仅为 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( 类型)