解除分配后指针的状态

时间:2012-06-25 08:30:41

标签: c memory-management

调用free()函数后,动态分配的内存指针指向什么。 指针是否指向NULL,或者它仍指向在解除分配之前指向的相同位置。 free()的实现是否具有某种标准,或者它在不同平台中的实现方式不同。

uint8_t * pointer = malloc(12);
printf("%p", pointer); // The current address the pointer points to
free (pointer);
printf("%p", pointer); // must it be NULL or the same value as before ?

编辑: 我知道printf会产生相同的结果,我只是想知道我是否可以依赖于不同的实现。

4 个答案:

答案 0 :(得分:5)

不修改指针值。您将指针(内存地址)按值传递给free()free()函数无法访问pointer变量,因此无法将其设置为NULL

两个printf()调用应产生相同的输出。

答案 1 :(得分:4)

根据标准(C99的6.2.4 / 2):

  

当指向的对象时,指针的值变得不确定   到达其生命的尽头。

实际上,我所知道的所有实现都会为您的示例代码打印两次相同的值。但是,允许当你释放内存时,指针值本身就变成了陷阱表示,当你尝试使用指针的值时,实现会做一些奇怪的事情(即使你没有取消引用它。)

假设某个实现想要做一些不寻常的事情,我认为硬件异常或程序中止是最合理的。你可能不得不想象一个实现/硬件做了很多额外的工作,所以每次将指针值加载到寄存器中时,它都会以某种方式检查地址是否有效。这可以通过在内存映射中检查它(在这种情况下,我认为我的假设实现只会在包含分配的整个页面已被释放和取消映射时陷阱)或其他一些方法。

答案 2 :(得分:1)

free()仅释放内存。指针仍指向旧位置(悬空指针),您应手动将其设置为NULL

将指针设置为NULL是一种很好的做法。由于内存位置可能会被重用于其他对象,因此您可以访问和修改不属于您的数据。这特别难以调试,因为它不会产生崩溃,或者在某些无关紧要的情况下产生崩溃。如果您访问不存在的对象,设置为NULL将保证可重现的崩溃。

答案 3 :(得分:0)

我在C ++中试过这段代码

#include<iostream>
using namespace std;
int main(void)
{
    int *a=new int;
    *a=5;
    cout<<*a<<" "<<a<<"\n";
    delete a;
    *a=45;
    cout<<*a<<" "<<a<<"\n";
}

输出是这样的

5 0x1066c20
45 0x1066c20

再次跑步产生了类似的结果

5 0x13e3c20
45 0x13e3c20

因此,似乎在gcc中,指针在释放后仍然指向相同的内存位置。 此外,我们可以修改该位置的值。