C++ C++;如果类的成员
我目前正在使用一个特殊的库,它不是用STL容器构建的。在将一些函数重构为类时,我遇到了基于以下模式的堆栈溢出C++ C++;如果类的成员,c++,arrays,stack-overflow,C++,Arrays,Stack Overflow,我目前正在使用一个特殊的库,它不是用STL容器构建的。在将一些函数重构为类时,我遇到了基于以下模式的堆栈溢出 class Base { float values[1920 * 1080]; // causes overflow public: Base() {} }; int main() { float values[1920 * 1080]; // does not Base t; } 我知道您可以为Base::values分配动态内存,但为什么它不会在m
class Base
{
float values[1920 * 1080]; // causes overflow
public:
Base() {}
};
int main()
{
float values[1920 * 1080]; // does not
Base t;
}
我知道您可以为Base::values
分配动态内存,但为什么它不会在main
中导致堆栈溢出,但在Base
中,为什么Base
的堆栈空间看起来小得多?也许是我错过了什么
(上面的示例使用Visual Studio 2017编译,默认标志)1920*1080*sizeof(float)足以破坏堆栈。(8 Mb)
确保编译器不会通过设置元素来删除数组值
更改基数如下
class Base {
float * values;
Base() {
values = new float[1920*1080];
}
~Base(){
delete [] values;
}
}
还要修复复制和分配运算符。如果您这样做:
浮点值[1920*1080]代码>
您正在将浮点数组分配到堆栈上
浮点占用4个字节(32位),因此大小为[1920*1080]的浮点数组将占用1920*1080*4=8294000字节
堆栈中包含的字节太多,因此会出现堆栈溢出和程序崩溃
但是,如果您这样做:
float*值=新的float[1920*1080]代码>
将浮点数组分配到堆上,这称为动态数组
堆比堆栈大得多,仅受可用内存的限制,始终能够容纳8294000字节。因此,这样做不会导致堆栈溢出
当您访问动态数组的一个元素时,它是从内存加载到堆栈上的,它不需要加载所有元素,只需加载您需要的元素,因此在访问数组元素时也不会出现堆栈溢出。缺点是访问每个变量所需的时间较长(仍然只有大约50到150纳秒),当使用delete[]
操作符不再需要数组时,需要显式释放分配给动态数组的内存,否则会出现内存泄漏。浮点值[1920*1080]代码>作为“未使用的变量”删除?或者堆栈大到足以容纳1920*1080个浮点数,但不足以容纳更多1920*1080个浮点数?仅根据我的假设)如果只在main()中保留这两行中的一行,是否会导致堆栈溢出?@KjMag将main()
保留为JustBase t
始终会在当前数组大小为Base::values
的情况下导致崩溃,无论float values[…]
是否存在。是否在发布模式下编译?尝试调试模式。在main()中只保留普通浮点数组不会导致堆栈溢出,对吗?您是否可以检查调试和/或关闭优化时的行为是否相同?这是否意味着main()
中的value
直接映射到内存中?或者编译器由于已知的主用法而创建了一个大堆栈,或者它不使用内存,因为我理解堆栈内存和堆内存之间的区别,但没有意识到堆栈内存是如此之小。但是,在main()
中声明的float值[1920*1080]
存储在哪里,为什么不存储堆栈?