如何打印悬空指针以进行演示?

6

我正在尝试向某人解释为什么他们有一个悬空指针以及free函数的实际作用(指针是值,因此按值传递),但为此我认为需要一种打印指针的方法,而不是“不确定”的(如printf("%p", ptr))。

memcpy能行吗?

char buf1[sizeof(char *)];
char buf2[sizeof(char *)];
char *malloced = malloc(10);
memcpy(buf1, &malloced, sizeof(char *));
free(malloced);
memcpy(buf2, &malloced, sizeof(char *));
for (int i=0; i<sizeof(char *); i++) {
    printf("%hhd %hhd / ", buf1[i], buf2[i]);
}

3
我很确定没有合法的方式可以处理悬空指针,所以直接使用"%p"吧。 - Ry-
@DavidSchwartz 我想要一个可视化工具,显示指针在调用free之前和之后的值是相同的(因为指针是按值传递的,所以你正在将该值复制到free中,而free无法修改该值的副本)。 - SoniEx2
1
free 被定义为 void free(void *ptr) 而不是 void free(void **ptr_to_ptr)。据我所知,它实际上不能改变指针。 - SoniEx2
@SoniEx2 值是两个因素的组合——位模式和位模式到值的映射。即使函数无法改变位模式,它仍然可以改变位模式到值的映射,从而改变值。标准明确指出,您不能对悬空指针的值做出假设。那么为什么您要这样做呢? - David Schwartz
@SoniEx2 我不太确定怎么做。你觉得这样会有什么帮助吗?你可以使用 memcpy 复制比特位模式,但接下来呢?如果你查看比特模式,它并不能告诉你值是否发生了变化。你能知道比特模式是否改变了,但你已经知道它不会改变。 - David Schwartz
显示剩余11条评论
1个回答

9

根据C标准的严格解读,您无法对悬空指针执行任何操作:“不确定状态”是内存的状态,它包含了悬空指针,同时也描述了未初始化自动变量的内容,如果连续两次读取这些变量,它们可能具有不同的值(*)。

唯一的解决方法是在指针“仍然有效”的情况下将其转换为 uintptr_t 。转换的结果是一个整数,并具有整数的属性:

#include <stdint.h>
...
char *malloced = malloc(10);
uintptr_t ptr_copy = (uintptr_t) malloced;
...
free(malloced);
// it is valid to use ptr_copy here to display what the address was.
printf("The pointer was at: %" PRIxPTR "\n", ptr_copy);

(*) C11标准区分自动变量(其地址未被获取,“可以使用register存储类声明”), 但{{link2:Clang不关心}}。

具体回答您关于使用memcpy的建议,请注意{{link3:memcpy复制不确定内存会产生不确定内存}}。


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