【问题标题】:What is the source of this 'realloc(): invalid next size' error这个“realloc():无效的下一个大小”错误的来源是什么
【发布时间】:2018-06-11 09:22:58
【问题描述】:

我已经阅读了其他此类问题,但我仍然无法弄清楚为什么我的代码中会出现此错误。

这是我的代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct {                 
    int len;
    int str[0];
} bit_str;

bit_str * input(void);
void print_bitstr(bit_str * s);

int main(void)
{
    bit_str * s1 = input();
    print_bitstr(s1);

    return 0;
}

bit_str * input(void)
{
    bit_str *s = (bit_str *) malloc(sizeof(bit_str)); 
    int count = 0, bit;

    while ((bit = getchar()) != 'k'){
        s = (bit_str *) realloc(s, sizeof(*s) + sizeof(int));           
        s->str[count++] = bit - 48;
    }

    s->len = count;
    return s;
}

void print_bitstr(bit_str * s)
{
    for (int i = 0; i < s->len; i++)
        printf("%d ", s->str[i]);
    printf("\n");

    return;
}

此代码是我试图将两个位字符串添加在一起的程序的一部分(作为数据结构书中的练习)。

我创建了一个结构来存储位字符串及其长度。使用输入函数中的 malloc 初始化结构。每次添加新位时都会重新分配。这些位使用 getchar 读取,位串的结尾由字母“k”划分。

当我编译代码时,它完全适用于 6 位。但是如果我尝试输入 7 位,它会崩溃并出现以下错误:

> realloc(): invalid next size  

我已阅读其他有类似错误的帖子,但我无法弄清楚为什么我的代码中会出现此错误。我确保当我重新分配时,我使用 sizeof 运算符来获取大小,而不是绝对值。

有人可以帮我弄清楚我在这里做错了什么吗?

【问题讨论】:

  • int str[0]; 在标准 C 中是不允许的
  • 我认为你不应该这样做,除非你对 C 有很多经验。使用经典分配方法而不是 FMA。
  • 确实,您必须使用int str[];int str[0] 是 GCC 扩展,但标准 int str[] 在那里工作 - 从错误消息看来,您正在使用 glibc + gcc。
  • 另外,不要强制转换malloc的返回值。

标签: c realloc


【解决方案1】:

sizeof(*s) 在编译时进行评估;它不知道动态分配,例如mallocrealloc

因此,即使您尝试将 sizeof(int) 字节动态添加到当前分配中:

s = (bit_str *) realloc(s, sizeof(*s) + sizeof(int)); 

这总是导致s 指向sizeof(bit_str) + sizeof(int) 字节。

当然,在无操作realloc 之后,您继续向缓冲区写入更多字节,超出缓冲区并导致未定义的行为

【讨论】:

  • 但是在我向它写入任何字节之前,我会重新分配它并将它的大小增加一个整数。每次我写它时都会这样做。
  • 你只能添加一个int——你不知道它的大小。 `sizeof(*s)` 不知道你上次分配的大小。
  • @JonathonReinhart:我认为您需要解释一下 sizeof 是基于静态类型信息,而不是当前块的动态大小...
  • 我想我知道,因为我使用 sizeof(*s) + sizeof(int)。所以将它重新分配为它自己的大小 + 一个 int 的大小。至少这就是我打算使用我的代码的目的。
  • @JonathonReinhart sizeof 可以在运行时进行评估,例如int x[rand() % 6 + 1]; printf("%d\n", (int)sizeof x);。在这个问题中,s 的类型为 bit_str *,所以 *s 的类型为 bit_str,我们看到的是该类型的大小
猜你喜欢
  • 1970-01-01
  • 2015-04-12
  • 1970-01-01
  • 2016-01-02
  • 2020-12-27
  • 2019-07-24
  • 2014-10-13
相关资源
最近更新 更多