0

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

4 回答 4

5

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

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

于 2012-06-25T08:32:26.727 回答
4

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

当指针指向的对象到达其生命周期的末尾时,指针的值变得不确定。

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

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

于 2012-06-25T08:40:46.400 回答
1

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

将指针设置为NULL是一个好习惯。由于内存位置可能会被其他对象重用,您可能能够访问和修改不属于您的数据。这特别难以调试,因为它不会产生崩溃,或者在某些不相关的点产生崩溃。如果您访问不存在的对象,设置为NULL将保证可重现的崩溃。

于 2012-06-25T08:31:59.287 回答
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 中,指针在释放后仍指向相同的内存位置。此外,我们可以修改该位置的值。

于 2018-05-06T15:44:30.947 回答