对私有数据进行类 - 在堆栈或堆上

Class private data - on stack or heap

本文关键字:堆栈 数据      更新时间:2023-10-16

在下面的代码中:

class Array {
   public:
      int& operator[] (unsigned i) { if (i > 99) error(); return data[i]; }
   private:
      int data[100];
};
int main()
{
   Array a;
   a[10] = 42;
   a[12] += a[13];
   ...
}

(如果我错了,请纠正我)数组类型的变量 a 在堆栈上,因为 new 未用于分配它。Array 类有 int data[100],运算符重载返回对数据中特定索引的引用。

参考问题。

我的问题是 int data[100] 是在堆栈上还是堆上?我认为它不应该是堆栈,否则像上面的引用返回如何仍然有效。

谢谢。

它在堆栈上,因为正如您所注意到的,a是在堆栈上分配的。

堆栈就像堆一样是内存;您可以返回对其中一部分的引用,就像在堆上分配的内存一样。唯一的区别在于内存的管理方式。

您唯一需要注意的是不要访问已解除分配的内存;对于堆栈,这发生在a的作用域结束时,而堆分配的数据必须显式删除。

在你提到的问题中,对堆栈上声明的变量的引用是从函数返回的;在这种情况下,当函数退出时,变量被销毁,这就是该代码错误的原因。但是,在您的情况下,您将返回对data的一部分的引用,其生存期与Array对象的生存期匹配;因此,只要a没有被破坏,以这种方式访问它的数据是安全的。

正如你所说,"数组类型的变量 a 在堆栈上"。从技术上讲,名为 a 的对象位于堆栈上。这意味着对象a的所有成员变量都在堆栈上。

这意味着返回对成员数组中名为 data 的元素的引用是非常危险的。编译器将允许它,但如果在变量a超出范围时尝试访问此引用,则会遇到未定义的行为。

在您的示例中,对operator[]()的所有调用都在同一方法中,因此一切都很好。

它在堆栈上。为什么引用返回会有问题?您可以毫无问题地创建和使用对堆栈上事物的引用。

void foo(void)
{
 int i;
 int& j = i; // reference to variable on the stack
 j = 2;
}

您认为这里可能存在什么问题?

我的问题是 int data[100] 是在堆栈上还是堆上?我认为它不应该是堆栈,否则像上面的引用返回如何仍然有效。

它分配了自动存储持续时间,即堆栈,而不是堆。 您没有动态分配任何内容,因此不会发生动态(堆)分配。 这将是一件可怕的事情,C++就是不为你不使用的东西付费。

如果data离开了其声明范围,即Array实例的范围,则对data元素或data本身的引用将是无效的。 现在,Array类型是否应该使用动态分配? 几乎可以肯定,是的,对于通用容器。 您有责任确保不会保留指向错误数据的引用或指针。

它将

在堆栈上。 如果在"a"超出范围后尝试使用该引用,则会得到未定义的行为。 希望它很快就会崩溃。