本文介绍了realloc(): 无效的下一个大小 - realloc 动态结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始学习 C 中的结构体.今天我发现了一个我无法解决的问题.我有这个代码:

I started learning about struct in C. Today I found a problem, that I can't solve. I have this code:

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"时阅读,但它工作了 2 倍,然后我得到这个错误 realloc(): invalid next size: 0x0000000001559010 ***我尝试使用 valgrind 并且有更多错误:

I want to read while user don't type '\n', but it works 2x and then I get this erorr realloc(): invalid next size: 0x0000000001559010 ***I tryed use valgrind and there are more errors:

==7662== 大小为 8 的无效写入
==7662== 在 0x56AEBB4:_IO_vfscanf (vfscanf.c:2328)
==7662== 由 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== 由 0x400847: readFraze() (main.c:25)
==7662== by 0x400818: main (main.c:15)
==7662==
==7662== 条件跳转或移动取决于未初始化的值
==7662== 在 0x56BFCA2:getdelim (iogetdelim.c:63)
==7662== by 0x40093E: readFraze() (main.c:44)
==7662== by 0x400818: main (main.c:15)

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

Can anyone tell me, what am I doing wrong?

推荐答案

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

When you see a backtrace involving malloc, realloc or free, it means your heap is corrupted: your program overwrote some data structures used by the memory management system. The most common causes for that are writing past the bounds of a block allocated by malloc (buffer overflow) and continuing to use a memory block allocated by malloc after calling free on it (use after free).

正如 Weather Vane 已经在评论中提到的,您传递给 mallocrealloc 用于 s 与您对 s 的使用不匹配.s是一个指向struct fraze的数组的指针,你使用的元素最多可达这个数组的k,所以内存块一定很大足够 k+1struct fraze 类型的元素.鉴于您的分配策略,这意味着您必须为 struct fraze 类型的 i 元素留出空间.但是您的实际分配仅用于 sizeof( int ) 字节,这还不够.

As Weather Vane already mentioned in a comment, the size you pass to malloc and realloc for s doesn't match your usage of s. s is a pointer to an array of struct fraze, and you use elements up to k of this array, so the memory block must be large enough for k+1 elements of type struct fraze. Given your allocation policy, that means you must leave room for i elements of type struct fraze. But your actual allocation is for only sizeof( int ) bytes, which is not enough.

做到这一点

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;

这篇关于realloc(): 无效的下一个大小 - realloc 动态结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-25 09:03