c++ - const 引用的内存位置

标签 c++ reference constants

我有以下 C++ 代码,我正在运行 g++ (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0:

#include <iostream>

const int& getConst() {
  int x = 10;
  printf("x ptr: %p\n", &x);
  const int &y = 10;
  printf("y ptr: %p\n", &y);
  return y;
}

int main() {
  int start = 0;
  printf("start ptr: %p\n", &start);
  const int &t = getConst();
  printf("t: %d\n", t);
  printf("t ptr: %p\n", &t);
  int end = 0;
  printf("end ptr: %p\n", &end);
  return 0;
}

这段代码的输出如下:

root@78600f6683dd:/home/test/question# ./a.out
start ptr: 0x7ffdcd2381f8
x ptr: 0x7ffdcd2381c8
y ptr: 0x7ffdcd2381cc
t: 10
t ptr: 0x7ffdcd2381cc
end ptr: 0x7ffdcd2381fc

我对结果有两点感到困惑:

  1. 函数main()startend的内存位置分别是0x7ffdcd2381f8和0x7ffdcd2381fc。 main 函数变量的内存位置是递增的。 main函数调用了getConst()函数,但是函数getConst()中变量的位置是0x7ffdcd2381c8和0x7ffdcd2381cc,与中的变量相比都是递减的>main() 函数。因为 main 函数调用 getConst() 函数,所以 getConst() 的位置不应该在堆栈顶部到 main( )?

  2. getConst() 函数中,y 是对 10 的 const 引用。据我了解,程序是这样的,一个 临时 int 变量 被创建,值为 10,并且 y references 指向它。从程序的输出中可以看出,yt 都指向相同的内存位置。但是临时变量是定义在栈中的变量,不是应该在getConst()函数返回后清理吗?如果是这样,t 怎么还能得到正确的值呢?

最佳答案

您的代码具有未定义的行为,因为它正在返回对临时变量的引用,所以任何事情都可能发生。

然而,实际发生的情况可能是返回的引用基本上是一个指针,指向的内存不再有效,但指针本身只是一个数字,因此您能够打印它的值也就不足为奇了。打印引用的值可能会起作用,因为运行时不会“清理”释放的堆栈内存,这会浪费时间,当内存被重新使用时,它将被重新初始化。如果您调用一个包含未初始化变量的新函数,那么如果它们也具有与 getConst 中设置的值相同的值也就不足为奇了。这当然都是未定义的行为。

传统上堆内存从内存底部增长,栈从顶部增长,当两者相遇时你的程序就内存不足了。对于现代虚拟内存方案,这不再是字面上的情况,但堆栈通常仍然是一个固定大小的内存块,从末尾到前面使用,因此新堆栈分配的地址低于以下地址并不罕见旧的。这就是溢出堆栈变量如此危险的原因,您不是在覆盖未使用的内存,而是在覆盖堆栈中较早的变量。

关于c++ - const 引用的内存位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59589197/

相关文章:

C++11 正则表达式子匹配

c++ - 数据竞赛?段错误,但是问题出在哪里呢?

C++链表指针总是nullptr

c++ - 关于引用到常量(和指针到常量)的弱语义

c++ - 'registering' 对象放入同一个类中的静态数组时内存泄漏

c++ - 如何读取 Visual C++ 2010 生成的程序集输出?

带引用的 C++ 多态性

Java动态绑定(bind)和方法重写过程

c - 函数调用中指向 const 的指针

constants - 如何在verilog中使用const