2017-08-20 48 views
2

C++數組會導致崩潰我目前正在使用未使用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小得多?也許這很明顯,我只是想念。

+0

'float values [1920 * 1080];'被淘汰爲「未使用的變量」?或者堆棧足夠大以容納1920 * 1080浮點數,但不足以容納1920 * 1080浮點數?只是我的假設) – WindyFields

+1

如果您只在main()中保留這兩行中的一行,是否會導致堆棧溢出? – KjMag

+0

@KjMag只要'Base t'離開'main()',在當前數組大小爲'Base :: values'的情況下總會導致崩潰,無論'float value [']是否存在。 – Alexander

回答

0

1920×1080×的sizeof(浮動)是sufficent吹堆(以上實例使用Visual Studio 2017,缺省標誌編譯)。 (8 Mb)

確保編譯器不會通過設置元素來移除值數組。

改變基地如下。

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

還修復了複製和賦值操作符。

+0

這是否意味着'main()'中的'values'被直接映射到內存中? – Alexander

+0

由於已知的主要用法,編譯器創建了一個大堆棧,或者由於as-if規則,它不使用內存 – mksteve

0

如果你這樣做:

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 []運營商或您不再需要陣列時,需要明確釋放分配給動態陣列的內存會得到內存泄漏。

+0

我理解堆棧和堆內存之間的差異,但沒有意識到堆棧內存如此之小。但是,在main()中聲明的浮點值[1920 * 1080]在哪裏存儲呢,爲什麼不是堆棧呢? – Alexander