对私有数据进行类 - 在堆栈或堆上
Class private data - on stack or 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];
...
}
(如果我错了,请纠正我)数组类型的变量 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"超出范围后尝试使用该引用,则会得到未定义的行为。 希望它很快就会崩溃。
- 拥有映射的现代方法,该映射可以指向或引用已在堆栈上分配的不同类型的数据
- 使用带有链表的堆栈数据结构将中缀转换为后缀
- C++,在对象内分配多个数据时,堆栈分配是否更有效? 在下面的程序中,类A_Heap的效率会更低吗?
- 函数超过堆栈大小,请考虑将一些数据移动到堆 (C6262)
- 自定义堆栈上 std::string 数据的输出
- 是否可以检查存储在堆栈上的单词是否是回文,而C++中没有任何附加数据结构
- 递归如何使用堆栈数据结构
- 比较堆栈数据结构 c++
- 使用提升库在队列和堆栈数据结构上保存和加载数据时出错
- 堆栈(数据结构)实现
- c++:堆栈上的数据,而不初始化它
- 使用临时数据表修复内存泄漏(堆与堆栈)
- 将记录推送到数据结构中的堆栈
- 尝试修改 Hbitmap 数据时出现堆栈错误
- 对私有数据进行类 - 在堆栈或堆上
- 如何拥有一个具有多个数据类型的C++堆栈
- 我需要一个像堆栈一样的数据结构,但具有随机访问,但是,我应该实现什么
- 如何用堆栈数据结构替换递归功能调用
- C++ 中的动态堆栈数据类型声明
- 理解堆栈数据结构并实现它