[英]Object is still reachable after leaving the function
#include <stdio.h>
typedef struct node {
int val;
} node;
node *copy(node *x) {
node *tmp = &((node){.val = 10});
return tmp;
}
int main() {
// node *a = &((node){.val = 9});
node *a = 0;
a = copy(a);
printf("%d\n", a->val);
return 0;
}
As far as I know, every object inside the stack of function will be not accessible after leaving function.据我所知,离开 function 后,function 堆栈中的每个 object 都将无法访问。 However, it doesn't.
然而,事实并非如此。
I used GDB to inspect where is the object.我使用 GDB 检查 object 在哪里。
(gdb) b 9
(gdb) b 16
(gdb) r
(gdb) p $rsp
$8 = (void *) 0x7fffffffdcc0
(gdb) p $rbp
$9 = (void *) 0x7fffffffdcf0
(gdb) p tmp
$7 = (node *) 0x7fffffffdcdc
(gdb) c
(gdb) p $rsp
$10 = (void *) 0x7fffffffdd00
(gdb) p $rbp
$11 = (void *) 0x7fffffffdd10
(gdb) p a
$12 = (node *) 0x7fffffffdcdc
You can see the variable 'a' point to 0x7fffffffdcdc
which is not between $rsp and $rbp.您可以看到变量 'a' 指向
0x7fffffffdcdc
,它不在 $rsp 和 $rbp 之间。 Finally the program prints "10" without any error message.最后程序打印“10”,没有任何错误信息。 I can't understand why it can works.
我不明白为什么它可以工作。
When an object goes out of scope, you can no longer access it by its symbol name.当 object 超出 scope 时,您无法再通过其符号名称访问它。
If you take a pointer (memory address) to the object and return it as you have, the pointer refers to the memory where the object once existed .如果您将指针(内存地址)指向 object 并按原样返回,则该指针指的是 memory曾经存在的 object 。 Nothing specifically happens to that memory content when the object goes out of scope - it just becomes available for other purposes.
当 object 超出 scope 时,memory 内容没有发生任何特别变化 - 它只是可用于其他目的。 So if that memory has not yet been reused, it is not remarkable that the memory occupied by the object has not changed.
所以如果那个memory还没有被重用,那么object占用的memory没有变化就不足为奇了。
You are looking at a ghost of an object.您正在查看 object 的幽灵。 It won't survive long.
它不会存活很长时间。 for example if you do:
例如,如果你这样做:
printf("%d\n", a->val);
printf("%d\n", a->val);
You will most likely find that by the second printf()
call it has been modified, because the printf()
call has used the stack space previously occupied by tmp
in copy.您很可能会发现在第二次
printf()
调用时它已被修改,因为printf()
调用已经使用了先前由tmp
在副本中占用的堆栈空间。
Strictly it is undefined behaviour and anything could happen.严格来说,这是未定义的行为,任何事情都可能发生。 In practice what I have described is " typical " - if something different happens for you, then shrug , other things are possible.
在实践中,我所描述的是“典型的”——如果你发生了不同的事情,那么耸耸肩,其他事情也是可能的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.