有人声称
a compiler is free to reuse the pointer variable for some other purpose after the realloc being freed, so you have no guarantee that it has the same value as it did before
ie
void *p = malloc(42);
uintptr_t address = (uintptr_t)p;
free(p);
// [...] stuff unrelated to p or address
assert((uintptr_t)p == address);
可能会失败。
C11 附件 J.2 内容如下
指向通过调用 free 或 free 释放的空间的指针的值
使用 realloc 函数 (7.22.3) [未定义]
但附件当然不是规范性的。
附件 L.3(这是规范性的,但可选)告诉我们,如果
指向通过调用 free 或 realloc 释放的空间的指针的值
使用函数(7.22.3)。
结果允许是关键的未定义行为。
这证实了这一说法,但我希望看到标准本身而不是附件中的适当引用。
当一个对象到达其生命周期结束时,所有指向它的指针都变成不定。这同样适用于块范围变量和分配的内存。适用的条款是 C11 中的 6.2.4:2。
对象的生命周期是程序执行的一部分,在此期间保证为其保留存储空间。对象存在,具有常量地址,并在其整个生命周期中保留其最后存储的值。如果一个对象在其生命周期之外被引用,则行为是未定义的。当指针指向(或刚刚过去)的对象到达其生命周期结束时,指针的值变得不确定。
将不确定内存用于任何事情,包括明显无害的比较或算术,都是未定义行为(在 C90 中;后来的标准使问题变得非常复杂,但编译器继续将不确定内存的使用视为未定义行为)。
举个例子,下面的程序如何打印p
and q
既不同又相同?显示不同编译器的执行结果here.
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main(int argc, char *argv[]) {
char *p, *q;
uintptr_t pv, qv;
{
char a = 3;
p = &a;
pv = (uintptr_t)p;
}
{
char b = 4;
q = &b;
qv = (uintptr_t)q;
}
printf("Roses are red,\nViolets are blue,\n");
if (p == q)
printf ("This poem is lame,\nIt doesn't even rhyme.\n");
else {
printf("%p is different from %p\n", (void*)p, (void*)q);
printf("%"PRIxPTR" is not the same as %"PRIxPTR"\n", pv, qv);
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)