简体   繁体   English

Object 离开 function 后仍然可以到达

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM