【问题标题】:Error with free() in C (invalid next size) after realloc重新分配后 C 中的 free() 出错(下一个大小无效)
【发布时间】:2021-05-02 08:54:56
【问题描述】:

几个小时以来,我一直试图找出问题所在,但无法解决。这是代码,当然要长得多,但我已将其简化为问题本身。

#define BUFFER_SIZE 60
char *str;

void readText() {
    char read_char;
    int i = 0;
    str = (char *) calloc(BUFFER_SIZE, sizeof(char));
    while ((read_char = getchar()) != EOF) { /* user hits ctrl+d */
        *(str+i) = read_char;
        i++;
        if (i % BUFFER_SIZE == 0) {
            str = (char *) realloc(str, BUFFER_SIZE * sizeof(char));
        }
    }
    textSize = i;
    /* Here I print the text... same error printing or not printing */
    free(str);
}

}

只有当输入文本超出缓冲区大小时才会出现错误。

(编辑: if (i % BUFFER_SIZE == 0) 所以它每次达到60,但错误是一样的 )

谢谢

【问题讨论】:

  • 缓冲区溢出导致未定义行为。不要让它发生。
  • 顺便说一下,getchar 函数返回一个 int,这对于与 intEOF 进行比较非常重要。
  • 另一方面,对于任何指针或数组p 和索引i,表达式*(p + i)完全等于p[i]。后者 (p[i]) 通常更容易阅读和理解,而且写起来更少。
  • 查看 realloc 与原始 callocat all 分配的内存量有 any 差异吗?不。然后您立即离开缓冲区以调用 UB。同样糟糕的是,即使您在那里修复了大小,您也需要更新动态 容量,而不是固定的常量缓冲区大小。

标签: c free realloc


【解决方案1】:

那是因为你reallocating 大小相同,当字符串长大时需要使用新的大小:

while ((read_char = getchar()) != EOF) { /* user hits ctrl+d */
    if (i >= BUFFER_SIZE) {
        str = realloc(str, i);
    }
    *(str+i) = read_char;
    i++;
}

另外,您似乎忘记设置尾随 NUL,您需要它来构建有效(可打印)字符串,切换到

    if (i >= BUFFER_SIZE - 1) {

str[i] = '\0';

while 循环之后。

最后,更喜欢

size_t i = 0; // or better yet size_t len = 0;

结束

int i = 0;

将大小传递给realloc 和朋友。

【讨论】:

  • 对不起,我以为 realloc 在它所拥有的内容结束后添加,对它的理解不好。
猜你喜欢
  • 2012-10-23
  • 2017-03-28
  • 1970-01-01
  • 2011-08-13
  • 2012-10-25
  • 1970-01-01
  • 1970-01-01
  • 2015-04-16
  • 2020-08-29
相关资源
最近更新 更多