在C99中使用free()后的指针是否可用?

4

我的教授展示了以下代码:

void *p1=malloc(1024);
free(p1);
void *p2=malloc(1024);
if (p1==p2)
{
    printf("Now What?")
}

他说这是不安全的,但为什么?

我知道我们不应该尝试访问已释放的内存。然而,只要不尝试从指针所指向的位置读取数据,我们可以知道指针指向哪里,因为它只是一个普通指针。


无论哪种情况,请勿尝试从指针位置读取,因为在上述代码中,内存内容是不确定的。但是,如果 p1p2 具有相同的值,则使用哪一个都没有关系。 - Weather Vane
4
这段代码片段并不包含任何未定义的行为,因为它没有访问存储在 p1 中地址的内存。如果 p2p1 的值相同,你甚至可以访问该内存。如果 malloc 返回刚释放的内存地址,则取决于实现方式。 - Bodo
3
@Bodo,尽管你的评论得到了很多赞,但是它是不正确的。请看已发布的答案。 - Eugene Sh.
2个回答

3

这实际上是不安全的,因为指向已释放内存的指针是不确定的。

C标准的J.2附录给出了未定义行为的示例,其中包括以下内容:

  • 使用已结束生命周期的对象的指针的值(6.2.4)。

...

  • 使用指向由调用freerealloc函数释放的空间的指针的值(7.22.3)。

有关内存管理函数的第7.22.3p1节规定:

... 分配对象的生命周期从分配开始到释放为止 ...

而定义对象生命周期的第6.2.4p2节规定如下:

对象的“寿命”是程序执行期间为其保留存储空间的部分。对象存在,具有恒定的地址,并在其生命周期内保留其最后存储的值。如果对象在其生命周期之外被引用,则行为是未定义的。当指针所指向的对象(或刚好超过该对象)达到其寿命终点时,指针的值变得不确定。

0

上述代码的行为将是未定义的,因为指向的对象被free函数销毁了。标准已经在他们的草案中提到了这一点。

“如果一个指针值在指向的对象(或刚刚过去)达到其生命周期的末尾后用于评估,则行为是未定义的。”

他们还描述说,当指针指向的对象(或刚刚过去)达到其生命周期的末尾时,指针对象的表示变得不确定”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接