realloc(): 无效的下一个大小 - realloc 动态结构

Sch*_*ami 1 c struct realloc

我开始学习 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)

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

Gil*_*il' 5

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

正如Weather Vane在评论中已经提到的那样,您传递给mallocreallocfor的大小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,您将指针分配到的元素数组的大小si * sizeof(*s). 不要使用 sizeof( TYPE )