有人声称
编译器可以自由地将指针变量重用于其他目的之后
realloc被释放,所以你不能保证它具有与之前相同的价值
即
void *p = malloc(42);
uintptr_t address = (uintptr_t)p;
free(p);
// [...] stuff unrelated to p or address
assert((uintptr_t)p == address);
Run Code Online (Sandbox Code Playgroud)
可能会失败.
C11附件J.2读
使用指向通过调用free或realloc函数释放的空间的指针的值(7.22.3)[ 未定义 ]
但附件当然不是规范性的.
附件L.3(规范性的,但可选的)告诉我们,如果
使用指向通过调用free或realloc函数解除分配的空间的指针的值(7.22.3).
结果被允许是关键的未定义行为.
这证实了这一说法,但我希望从标准本身而不是附件中看到适当的引用.
以下代码运行编译器选项-O3
vs -O0
结果不同的输出:
#include <stdlib.h>
#include <stdio.h>
int main(){
int *p = (int*)malloc(sizeof(int));
int *q = (int*)realloc(p, sizeof(int));
*p = 1;
*q = 2;
if (p == q)
printf("%d %d", *p, *q);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我对结果感到非常惊讶.
用clang 3.4,3.5编译(http://goo.gl/sDLvrq)
使用编译器选项-O0
- 输出:2 2
使用编译器选项-O3
- 输出:1 2
这是一个错误吗?
有趣的是,如果我稍微修改代码(http://goo.gl/QwrozF),它的行为与预期一致.
int *p = (int*)malloc(sizeof(int));
*p = 1;
Run Code Online (Sandbox Code Playgroud)
在gcc上测试似乎工作正常.
我正在学习 C 编程并编写如下基本代码。
我了解到该函数可以释放由等等free()
分配的内存。calloc()
但是obj->id
,obj->name
在执行 Object_destroy 后,尽管已执行函数,但仍具有值free()
。
为什么会出现这种情况?释放内存不等于删除值吗?
#include <stdio.h>
#include <stdlib.h>
typedef struct Object* Object;
struct Object
{
int id;
char* name;
};
Object Object_new(int id, char* name)
{
Object obj = calloc(1, sizeof(struct Object));
obj->id = id;
obj->name = name;
return obj;
}
void Object_destroy(Object obj)
{
free(obj);
}
int main()
{
Object obj = Object_new(5, "test");
printf("%d\n", obj->id); // => 5
printf("%s\n", obj->name); // => test
Object_destroy(obj);
printf("%d\n", …
Run Code Online (Sandbox Code Playgroud)