类私有数据 - 在堆栈或堆上

时间:2012-11-29 01:29:29

标签: c++ stack heap

在以下代码中:

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];
   ...
}

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

参考question

我的问题是int数据[100]是在堆栈还是堆上?我认为它不应该是堆栈,否则如上所述的引用返回仍然可以工作。

感谢。

5 个答案:

答案 0 :(得分:2)

它在堆栈上,因为你已经注意到a被分配在堆栈上。

堆栈就像堆一样是内存;你可以返回对它的一部分的引用,就像在堆上分配的内存一样。唯一的区别在于如何管理内存。

唯一需要注意的是不要访问已经解除分配的内存;在堆栈的情况下,这发生在a范围的末尾,而必须明确删除堆分配的数据。

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

答案 1 :(得分:0)

它在堆栈上。为什么引用返回是一个问题?您可以毫无问题地创建和使用对堆栈中的内容的引用。

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

您认为这里有什么问题?

答案 2 :(得分:0)

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

答案 3 :(得分:0)

  

我的问题是int数据[100]是在堆栈还是堆上?我认为它不应该是堆栈,否则如上所述的引用返回仍然可以工作。

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

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

答案 4 :(得分:0)

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

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

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