我得到 "pointer being freed was not allocated"

I am getting "pointer being freed was not allocated"

我正在从标准输入读取。由于不知道要看多长,只好用malloc

我得到一个 正在释放的指针未分配

有时,它发生在 free(final) 之前,有时发生在 free(tmp) 之前。

我检查这两个指针在创建之后和释放之前是否正确为非空。有人可以指出我做错了什么吗?

total_size = 0;
final = (char *)malloc(sizeof(char) * 1);
if (!final)
{
    printf("Error Allocating Memory for final\n");
    return (NULL);
}
while ((ret = read(0, buf, BUF_SIZE)) > 0)
{
    tmp = (char *)malloc(sizeof(char) * ft_strlen(final));
    if (!tmp)
    {
        printf("Error Allocating Memory for tmp\n");
        return (NULL);
    }
    strcpy(tmp, final);
    if (final)
        free(final);
    buf[ret] = '[=11=]';
    total_size = total_size + ret;
    final = (char *)malloc(sizeof(char) * total_size);
    if (!final)
    {
        printf("Error Allocating Memory for final\n");
        return (NULL);
    }
    final = strcat(tmp, buf);
    if (tmp)
        free(tmp);
}
return (final);

我相信你对指针有点困惑。 当你写

final = (char *)malloc(sizeof(char) * total_size);

您分配相当于 sizeof(char) * total_size 的内存,然后 malloc returns 指向该内存的指针。 然后你继续写

final = strcat(tmp, buf);

其中还returns一个指针。您用 malloc(...) 分配的内存从未使用过。因此,当您随后尝试 if (final) free(final); 时,您并没有释放分配的内存。

只是注释掉

if (final)
    free(final);

final = (char *)malloc(sizeof(char) * total_size);
      if (!final){
          printf("Error Allocating Memory for final\n");
          return (NULL);
      }

删除了双重免费错误。希望这有帮助

这是你的问题:

final = (char *)malloc(sizeof(char) * total_size);

[...]

final = strcat(tmp, buf);

您正在泄漏分配的内存并混淆 *final*tmp。此后您可以释放其中的 一个 ,但是您不能在没有首先重新分配它以指向有效的动态分配块之前释放另一个。

总的来说,tmp 似乎会给您带来很多不必要的麻烦。据我所知,您只是想增加 final 指向的块的大小,这就是 realloc() 的用途:

size_t desired_size = total_size + ret + 1;  // need space for a terminator
char *tmp = realloc(final, desired_size);
if (!tmp) {
    perror("Error Allocating More Memory for final");
    // realloc() does not free the pointer on failure; at least GLIBC's doesn't
    free(final);
    return (NULL);
}
final = tmp;

buf[ret] = '[=12=]';

// strcat is wasteful if you already know the destination string's length
strcpy(final + total_size, buf);
total_size += ret;

重新分配的块可能会也可能不会从与原始块相同的位置开始,但 realloc() 会在必要时负责复制数据。