C++ C++;如果类的成员

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

我目前正在使用一个特殊的库,它不是用STL容器构建的。在将一些函数重构为类时,我遇到了基于以下模式的堆栈溢出

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()
保留为Just
Base t
始终会在当前数组大小为
Base::values
的情况下导致崩溃,无论
float values[…]
是否存在。是否在发布模式下编译?尝试调试模式。在main()中只保留普通浮点数组不会导致堆栈溢出,对吗?您是否可以检查调试和/或关闭优化时的行为是否相同?这是否意味着
main()
中的
value
直接映射到内存中?或者编译器由于已知的主用法而创建了一个大堆栈,或者它不使用内存,因为我理解堆栈内存和堆内存之间的区别,但没有意识到堆栈内存是如此之小。但是,在
main()
中声明的
float值[1920*1080]
存储在哪里,为什么不存储堆栈?