我的教授展示了以下代码:
void *p1=malloc(1024);
free(p1);
void *p2=malloc(1024);
if (p1==p2)
{
printf("Now What?")
}
他说这是不安全的,但为什么?
我知道我们不应该尝试访问已释放的内存。然而,只要不尝试从指针所指向的位置读取数据,我们可以知道指针指向哪里,因为它只是一个普通指针。
这实际上是不安全的,因为指向已释放内存的指针是不确定的。
C标准的J.2附录给出了未定义行为的示例,其中包括以下内容:
- 使用已结束生命周期的对象的指针的值(6.2.4)。
...
- 使用指向由调用
free
或realloc
函数释放的空间的指针的值(7.22.3)。
有关内存管理函数的第7.22.3p1节规定:
... 分配对象的生命周期从分配开始到释放为止 ...
而定义对象生命周期的第6.2.4p2节规定如下:
对象的“寿命”是程序执行期间为其保留存储空间的部分。对象存在,具有恒定的地址,并在其生命周期内保留其最后存储的值。如果对象在其生命周期之外被引用,则行为是未定义的。当指针所指向的对象(或刚好超过该对象)达到其寿命终点时,指针的值变得不确定。上述代码的行为将是未定义的,因为指向的对象被free函数销毁了。标准已经在他们的草案中提到了这一点。
“如果一个指针值在指向的对象(或刚刚过去)达到其生命周期的末尾后用于评估,则行为是未定义的。”
他们还描述说,当指针指向的对象(或刚刚过去)达到其生命周期的末尾时,指针对象的表示变得不确定”。
p1
和p2
具有相同的值,则使用哪一个都没有关系。 - Weather Vanep1
中地址的内存。如果p2
与p1
的值相同,你甚至可以访问该内存。如果malloc
返回刚释放的内存地址,则取决于实现方式。 - Bodo