const引用的内存位置

问题描述 投票:0回答:1

我具有以下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. 函数startendmain()的存储位置分别为0x7ffdcd2381f8和0x7ffdcd2381fc。 main功能的变量的存储位置在递增。主要函数调用getConst()函数,但是函数getConst()中变量的位置是0x7ffdcd2381c8和0x7ffdcd2381cc,与main()函数中的变量相比,它们的位置都在下降。由于main函数调用getConst()函数,因此getConst()的位置是否不应该位于main()的堆栈顶部?

  2. getConst()函数中,y是对10的常量引用。据我了解,过程是,创建一个temporary int variable的值为10,并且y references。从程序输出中可以看出,yt都指向相同的存储位置。但是临时变量是在堆栈中定义的变量,在getConst()函数返回后不应该清除它吗?如果是这样,t仍如何获得正确的值?

c++ reference const
1个回答
0
投票

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

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

通常,堆内存从内存的底部开始增长,而堆栈从顶部的向下增长,这两个条件相遇时,您的程序内存不足。对于现代的虚拟内存方案,从字面上不再是这种情况,但是堆栈通常仍然是固定大小的内存块,从头到尾使用,因此新堆栈分配的地址比旧的。这就是使堆栈变量溢出如此危险的原因,您不会覆盖未使用的内存,而实际上是在堆栈中更早地覆盖变量。

© www.soinside.com 2019 - 2024. All rights reserved.