c++?對象分配在棧上還是在堆上問題分析
c++的對象到底在棧上還是分配在堆上?
首先,毋庸置疑,使用new和malloc系列函數(shù)分配的對象,一定是在堆上的。
Object *obj = new Object();
有爭議的是
Object obj;
它是在棧上還是在堆上呢?
要回答這個問題,首先我們需要理解這句話的意思,這句話并不代表在棧上分配內(nèi)存,它代表的是讓obj具有“自動存儲(automatic storage)”的性質(zhì)。所謂的“自動存儲”,意思是這個對象的存儲位置取決于其聲明所在的上下文。如果這個語句出現(xiàn)在函數(shù)內(nèi)部,那么它就在棧上創(chuàng)建對象,此時obj變量和obj指代的對象(此時obj本質(zhì)上其實是obj指代對象的首地址)都在棧上。
如果這個語句不是在函數(shù)內(nèi)部,而是作為一個類的成員變量,則取決于這個類的對象是如何分配的??紤]下面的代碼:
class Test{ Object obj; } Test *test = new Test;
test指針是在棧上,它所指代的對象Test是存在堆上,那么obj變量和obj對象就在堆上。
class Test{ Object obj; } Test test;
test變量在棧上,test對象在棧上,那么obj變量和obj對象就在棧上。
遵循這么一個原則:
指針變量和普通變量由上下文定義,指針?biāo)赶虻膬?nèi)存在堆上,普通變量所指代的對象由上下文定義。
棧大小
棧大小是有默認(rèn)值的,如果申請的臨時變量太大就會超過棧大小,造成棧溢出。
它的默認(rèn)值是可以修改的,一般,在unix-like平臺,棧的大小是由環(huán)境變量控制的,所以不能通過設(shè)置編譯器(像gcc)的任何編譯標(biāo)志來設(shè)置;在windows平臺,棧的大小是包含在可執(zhí)行文件里的,它可以在visual c++的編譯過程中設(shè)置,但在gcc里是不可行的。
方法為:
項目->屬性->鏈接器->系統(tǒng)->堆棧保留大小 (字節(jié)數(shù))
在一般情況下,不同平臺默認(rèn)棧大小如下所示(僅供參考)
SunOS/Solaris 8172K bytes (Shared Version)
Linux 10240K bytes
Windows 1024K bytes (Release Version)
AIX 65536K bytes
演示
??臻g
代碼
#include <iostream> class Test { public: Test() { std::cout << "Test" << std::endl; } ~Test() { std::cout << "~Test" << std::endl; } private: char a[1024 * 1024]; }; class TestContainer { public: TestContainer() { std::cout << "TestContainer" << std::endl; } ~TestContainer() { std::cout << "~TestContainer" << std::endl; } private: Test test; }; int main(int argc, char* argv[]) { TestContainer t; while (1) {} return 0; }
- 棧大小1MB(默認(rèn)值),申請??臻g1MB
結(jié)果:程序崩潰,stack overflow
- 棧大小1048577(1024*1024+1,即1MB多1B),申請棧空間1MB
結(jié)果:程序正常
堆空間
#include <iostream> class Test { public: Test() { std::cout << "Test" << std::endl; } ~Test() { std::cout << "~Test" << std::endl; } private: char a[1024 * 1024]; }; class TestContainer { public: TestContainer() { std::cout << "TestContainer" << std::endl; } ~TestContainer() { std::cout << "~TestContainer" << std::endl; } private: Test test; }; int main(int argc, char* argv[]) { TestContainer* t = new TestContainer; while (1) {} return 0; }
- 棧大小1MB,申請堆1MB
結(jié)果:程序正常 - 棧大小1MB,申請堆10MB
結(jié)果:程序正常
以上就是c++ 對象分配在棧上還是在堆上問題分析的詳細(xì)內(nèi)容,更多關(guān)于c++ 對象堆棧分配的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C++中overload,override,overwrite的區(qū)別詳細(xì)解析
以下是對C++中overload,override,overwrite的區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下2013-09-09