繁体   English   中英

如果类的成员C ++数组导致崩溃

[英]C++ array causes crash if member of class

我目前正在使用的不是使用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)

确保编译器不会通过设置元素来删除values数组。

如下更改基础。

class Base {
    float * values;
    Base() {
         values = new float[1920*1080];
    }
    ~Base(){
         delete [] values;
    }
 }

还要修复复制和赋值运算符。

如果您这样做:

float values[1920 * 1080];

您正在将float数组分配到堆栈上。

浮点数占用4个字节(32位),因此大小为[1920 * 1080]的浮点数数组将占据1920 * 1080 * 4 = 8,294,000字节。

太多的字节无法包含在堆栈中,因此我们会发生堆栈溢出,程序崩溃。

但是,如果您这样做:

float* values = new float[1920 * 1080];

您正在将float数组分配到堆上,这称为动态数组。

堆比堆栈大很多,仅受可用内存的限制,并且将始终能够容纳8,294,000字节。 因此,这样做不会导致堆栈溢出。

当您访问动态数组的一个元素时,它会从内存中加载到堆栈中,它不需要加载所有元素,只需加载所需的元素,因此在访问数组元素时也不会导致堆栈溢出。 缺点是访问每个变量所花费的时间更长(仍然只有大约50至150纳秒),并且当不再需要使用delete []运算符来分配给动态数组的内存时,则需要显式释放分配给该数组的内存。否则会发生内存泄漏。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM