內存四區之代碼區,全局區,棧區和堆區


C++ 在程序執行時,將內存大致分為代碼區,全局區,棧區和堆區四個區域。不同的區域存儲不同的數據,賦予不同的生命周期,能夠更靈活地進行編程。

  1. 代碼區:存放函數體的二進制代碼,由操作系統管理創建,代碼區時共享的,對於頻繁被執行的程序,只需要存有一份代碼即可;
  2. 全局區:存放全局變量和靜態變量以及常量,在程序結束后由操作系統釋放;
  3. 棧區:由編譯其自動分配釋放,存放函數的參數值以及局部變量等;
  4. 堆區:一般由程序員通過 new 開辟空間,進行分配和釋放,若程序員不釋放,則程序結束時由操作系統回收

下面通過一個例子對全局區,棧區,堆區的數據聲明周期進行說明:

// 全局變量屬於全局區,由操作系統管理釋放
int g_a = 1;
int g_b = 2;
int main(void)
{
	cout << "g_a 的地址為:\t"<< int(&g_a) << endl;
	cout << "g_b 的地址為:\t" << int(&g_b) << endl;
	// 創建普通的局部變量,屬於棧區
	int a = 10;
	int b = 20;	
	cout << "a 的地址為:\t" << int(&a) << endl;
	cout << "b 的地址為:\t" << int(&b) << endl;
	// 創建靜態變量,屬於全局區
	static int s_a = 40;
	static int s_b = 50;
	cout << "s_a 的地址為:\t" << int(&s_a) << endl;
	cout << "s_b 的地址為:\t" << int(&s_b) << endl;
	// 程序員自己創建變量,屬於堆區
	int* d_a = new int(10);
	int* d_b = new int(20);
	cout << "d_a 的地址為:\t" << int(d_a) << endl;
	cout << "d_b 的地址為:\t" << int(d_b) << endl;
}

輸出結果為:

g_a 的地址為:  5300224		g_b 的地址為:  5300228	
a 的地址為:    6421316		b 的地址為:    6421304
s_a 的地址為:  5300232		s_b 的地址為:  5300236
d_a 的地址為:  9547944		d_b 的地址為:  9547992

我們從中可以看到,g_ag_bs_as_b 都屬於全局區,同理,ab 都屬於棧區,d_ad_b 都屬於堆區。由於棧區的數據在程序運行結束后會被編譯器自動銷毀,因此不要返回局部變量的地址,舉例如下:

int* func()
{
	int a = 10;	// 棧區數據,在程序執行完之后自動釋放
	return &a;	//雖然返回了a的地址,然而數據在func結束時已經被銷毀
}

int main(void)
{
	int* a = func();	// 此時a表示在函數func在棧區開辟的地址,但是其中的數據已被銷毀
	cout << "a 的地址為:\t" << int(a) << "a 存放的數據為:\t" << *a << endl;
	cout << "a 的地址為:\t" << int(a) << "a 存放的數據為:\t" << *a << endl;
}

輸出結果為:

a 的地址為:    7601480a 存放的數據為: 10
a 的地址為:    7601480a 存放的數據為: 2084553696

由於編譯器會對棧區的數據做一次保留,因此第一條的 cout 語句能夠正常輸出,然而第二次的輸出才是內存地址 a 中的數據。

相反,堆區數據由程序員自己進行管理,在程序執行完之后並不會自動釋放。當整個程序執行完畢之后會由操作系統釋放。

int* func()
{
	int * a = new int(10);	// 程序員使用new在堆區開辟空間,在程序執行完之后自動釋放
	return a;	//同樣返回了a的地址,然而只要程序沒有運行結束,除非程序員釋放,否則會一直保留
}

int main(void)
{
	int* a = func();	// 此時a表示在函數func在堆區開辟的地址,編譯器無法自動銷毀
	cout << "a 的地址為:\t" << int(a) << "a 存放的數據為:\t" << *a << endl;
	cout << "a 的地址為:\t" << int(a) << "a 存放的數據為:\t" << *a << endl;
}

輸出結果為:

a 的地址為:    23507016a 存放的數據為:        10
a 的地址為:    23507016a 存放的數據為:        10


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM