我得到了#34;指针被释放没有分配"

时间:2016-09-22 14:44:01

标签: c malloc free

我正在读书。由于我不知道我将阅读的内容的长度,我必须使用malloc。

我得到一个指针被释放未分配

有时,它发生在自由(最终)之前,有时在自由之前(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] = '\0';
    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);

2 个答案:

答案 0 :(得分:0)

我相信你在指针方面有点困惑。 当你写

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

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

final = strcat(tmp, buf);

这也返回一个指针。您使用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);
      }

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

答案 1 :(得分:0)

这对你来说是一个问题:

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] = '\0';

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

重新分配的块可能会或可能不会与原始块在同一个位置启动,但realloc()会在必要时负责复制数据。