在调用realloc()之前释放内存

时间:2016-12-15 15:06:50

标签: c pointers free dynamic-memory-allocation realloc

我的代码存在一些混淆。

我使用malloc()分配内存,释放它,然后使用与参数相同的指针ptr调用realloc(),但不要使用realloc的返回地址。

此代码编译并运行精细打印预期的字符串。我没想到它因为ptr之前被释放了。

但是,如果我将realloc()的返回地址分配给ptr而不是注释掉,那么当然会有预期的运行时错误,因为ptr将为NULL。

如果我只是将之前释放的ptr作为参数传递,它为什么会起作用。它显然再次分配内存?提前谢谢。

注意:此代码是故意编写的,目的只是为了尝试了解后台发生的情况。当然不建议取消引用悬空指针等。

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

int main()
{
    char* ptr;
    ptr = (char*)malloc(20);

    strcpy(ptr, "Hello");

    printf("Address before free : %d\n", ptr);
    printf("%s\n", ptr);

    free (ptr);

    printf("Address after free  : %d\n", ptr);
    printf("%s\n", ptr);

    realloc(ptr, 30);

    //ptr = realloc(ptr, 30); // causes runtime problem as expected

    strcpy(ptr, "Hello");

    printf("Address after realloc  : %d\n", ptr);
    printf("%s\n", ptr);

    return 0;
}

4 个答案:

答案 0 :(得分:6)

对于realloc(),具体而言,引用C11标准,章节§7.22.3.5

  

如果ptr是空指针,则realloc函数的行为类似于malloc函数   指定大小。否则,如果ptr与先前由内存返回的指针不匹配   管理功能,或者如果通过调用free或已释放空间   realloc函数,行为未定义。 [....]

也就是说,在这种情况下,您调用了 undefined behavior  在此之前,通过说

printf("Address after free  : %d\n", ptr);
printf("%s\n", ptr);

错误在哪里

  • %p是指针所需的格式说明符,其中参数已转换为void *,而不是%d
  • 尝试使用free() - d memory

,单独和单独都足以调用UB。

底线:在将指针传递给free()之前不要尝试realloc()指针,它会自行处理。

答案 1 :(得分:2)

名为realloc()的函数将重新分配内存区域,前提是它先前已分配malloc() calloc(),或realloc尚未释放free()。如果在free()之前的某个内存上调用realloc()将导致未定义的行为。不要将realloc()与已经释放的内存一起使用。

最诚挚的问候!

答案 2 :(得分:0)

程序的正确和演示版本:

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

int main()
{
    char* ptr;
    ptr = malloc(20);

    strcpy(ptr, "Hello");

    printf("Address : %p\n", (void*)ptr);
    printf("%s\n", ptr);

    ptr = realloc(ptr, 30);   // expand the memory pointed by ptr
                              // from 20 to 30 bytes.

    printf("Address after realloc  : %p\n", (void*)ptr);  // address most likely different
    printf("%s\n", ptr);                           // displays still "Hello"
                                                   // as realloc preserves memory content

    free(ptr);     // eventually free what has been allocated previously
    return 0;
}

示例输出:

Address : 00767BC8
Hello
Address after realloc  : 00768C38
Hello

BTW:realloc之前和之后的地址可能是相同的,具体取决于实现。

尝试重新分配更少的内存(例如18),地址很可能是相同的,但这仍然依赖于实现。

答案 3 :(得分:0)

ptr = realloc(ptr,30);

这很糟糕。如果重新分配失败,例如没有足够的内存并返回零,那么您松开了原来的指针,那儿就出现了内存泄漏