c++ - 模仿 "pointer to a reference"的类可以保存超出范围的变量吗?

标签 c++ pointers reference scope dynamic-memory-allocation

我想到了 C++ 中的一个奇怪作弊。通常,我无法将引用偷运出范围,因为我无法在包含范围中定义未初始化的引用。但是,我可以定义一个指向包含引用的类的指针,初始化失败,然后将初始化为局部变量的一些动态内存的地址分配给它。即使该动态对象包含对应该超出范围的变量的引用,指向的对象仍然具有具有相同值的有效引用!即使我告诉它是 -pedantic,g++ 也不会提示,所以我认为它是有效的。但是如何以及为什么?

struct int_ref
{
  int &x;
  int_ref(int &i): x(i) {}
};

#include <iostream>
using namespace std;

int main(void)
{
  int_ref *irp;
  int i = 1;
  int_ref a(i); // Creates an int_ref initialized to i
  irp = &a; // irp is now a pointer to a reference!
  // Prints 1
  cout << "irp->x = " << irp->x << " (i = " << i << ")" << endl;
  i = 2;
  // Prints 2
  cout << "irp->x = " << irp->x << " (i = " << i << ")" << endl;
  int j = 3;
  int_ref b(j);
  irp = &b;
  // Prints 3
  cout << "irp->x = " << irp->x << " (i = " << i << ", j = " << j << ")" << endl;
  i = 1;
  // Still prints 3
  cout << "irp->x = " << irp->x << " (i = " << i << ", j = " << j << ")" << endl;
  {
    int k = 4;
    irp = new int_ref(k);
    // k goes out of scope
  }
  int k = 1; // Doesn't affect the other k, of course
  // Prints 4 ?!
  cout << "irp->x = " << irp->x << " (i = " << i << ", j = " << j << ")" << endl;
}

编辑:这实际上可能是(如答案中所建议的)未诊断的悬空引用。如果我这样定义 int_ref 会怎么样:

struct int_ref
{
  const int &x;
  int_ref(const int &i): x(i) {}
};

const 引用不需要引用左值,因此没有明确定义的悬垂概念。代码还未定义吗?

最佳答案

你所做的有undefined behavior .

  {
    int k = 4;
    irp = new int_ref(k);
    // k goes out of scope
  }
  int k = 1; // Doesn't affect the other k, of course
  // Prints 4 ?! ***it could print 42 - no guarantees***
  cout << "irp->x = " << irp->x << " (i = " << i << ", j = " << j << ")" << endl;

您正在保留(并使用)对超出范围的对象的引用。无论您如何间接保留该引用,它都是未定义的行为。

未定义行为最糟糕的表现就是看起来工作正常。在这种情况下,您会有一种错误的安全感,但鼻腔守护进程可能会飞得到处都是,相信我 ;)

至于为什么即使在迂腐模式下编译器也不会提示,好吧,很难对代码进行这种静态分析来检测此类事情。所以它留给您自己注意。

关于c++ - 模仿 "pointer to a reference"的类可以保存超出范围的变量吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6719347/

相关文章:

c++ - QTabBar 选项卡大小不随样式表字体缩放

c++ - unique_ptr 的 remove_pointer

创建一个由 const char 指针指向的动态字符串数组

c++ - 未定义对类::函数错误的引用

c++ - 类似于内核版本 2.6.9(或更低版本)的 inotify 的类似工具

C++/Cx 是否可以使用 String 而不是 IAsyncAction 调用 CreateTask().then?

C++ 项目未编译

c - 获取输入并将其分配给指针数组中的结构,指向每个结构。

javascript - 在 Object 的情况下,Javascript 重新分配和引用如何工作?需要深入解释吗?

C++ 引用与局部变量