realloc( ): 下一个大小无效

realloc( ): Invalid next size

最小可重现示例:

prog.c

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

int main(void) {
  size_t bufsiz = 4, tmp;
  char *buffer;

  for (buffer = malloc(bufsiz), tmp = 0; buffer[tmp] = fgetc(stdin); ++tmp) {
    if (bufsiz == tmp && !realloc(buffer, bufsiz *= 2))
      return 1;
} }

Compile and run

gcc prog.c -o prog

echo duck | ./prog
realloc(): Invalid next size
Aborted

我已经阅读了很多类似的帖子,但找不到解决方案。

realloc return是指向分配的space的指针,它可能等于前一个指针,也可能是新值或空指针。你不能简单地调用 realloc(buffer, bufsiz *= 2);您必须使用 return 值作为新地址。

realloc return是一个新值时,之前的内存不再分配,不应该被使用。

您还需要一个不同的循环停止条件。使用 buffer[tmp] = fgetc(stdin) 作为测试将导致它在读取空字符时停止,但您不应期望空字符标记输入的结尾。当输入结束时,fgetc 将 return EOF,但 EOF 通常不能表示为 char 值。您必须存储(在 int 中)并测试 fgetc 的 return 值,然后再将其分配给 char.

对于初学者这个作业

buffer[tmp] = fgetc(stdin)

会导致访问数组外的内存。

例如,假设最初 bufsiz 等于 1

因此,在循环的第一次迭代之后,由于循环语句中的表达式 ++tmp,变量 tmp 将等于 1。而在循环的条件下会有

buffer[1] = fgetc(stdin)

但是 1 在这种情况下不是有效索引。

而且用户可以中断输入。在这种情况下,函数 fgetc 将 return EOF 您将尝试存储在字符数组中。

第二个问题是在这个表达式中

!realloc(buffer, bufsiz *= 2)

函数 realloc 的 returned 值即新分配内存的地址丢失。所以指针buffer将无效。

循环不可读。 non-readable 代码包含错误是编程的规律。

让代码更简单,更易读。