int a = 10; //全局變量,全局區。 全局變量初始化且初始化不爲0,存放在內存的.data段
int m; // 全局變量初始化爲0或者未初始化,存放在.bss段
class SomeClass
{
private:
int b; //由使用決定,在main函數中類SomeClass動態分配,因此在堆區。
static int c; //靜態成員在全局區。
};
int main()
{
int d = 0; //棧區。
SomeClass *p = new SomeClass; //棧區。
return 0;
}
內存空間分佈圖
內存分區 | 說明 |
---|---|
程序代碼區(code area) | 存放函數體(類成員函數和全局函數)的二進制代碼 |
靜態數據區(data area) |
注意: 未初始化的全局變量的默認值是 0,而未初始化的局部變量的值卻是垃圾值(任意值)。 靜態數據區的內存在程序結束後由操作系統釋放。 |
堆區(heap area) |
一般由程序員分配和釋放,若程序員不釋放,程序運行結束時由操作系統回收。malloc()、calloc()、free() 等函數操作的就是這塊內存 |
棧區(stack area) | 由系統自動分配釋放,存放爲運行函數而分配的局部變量、函數參數、返回數據、返回地址等。其操作方式類似於數據結構中的棧。 |
命令行參數區 | 存放命令行參數和環境變量的值,如通過main()函數傳遞的值。 |
提示:關於局部的字符串常量是存放在全局的常量區還是棧區,不同的編譯器有不同的實現,VC 將局部常量像局部變量一樣對待,存儲於棧(⑥區)中,TC則存儲在靜態數據區的常量區(②區)
內存模型示意圖
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int a = 0; // 全局初始化區(④區)
char *p1; // 全局未初始化區(③區)
int main()
{
int b; // 棧區
char s[] = "abc"; // 棧區
char *p2; // 棧區
char *p3 = "123456"; //
123456\0 在常量區(②),p3在棧上,體會與 char s[]="abc"; 的不同
static int c = 0; // 全局初始化區
p1 = (char *)malloc(10), // 堆區
p2 = (char *)malloc(20); // 堆區
// 123456\0 放在常量區,但編譯器可能會將它與p3所指向的"123456"優化成一個地方
strcpy(p1, "123456");
}
棧和堆的區別:
- 棧內存是由系統分配,系統釋放的;以函數爲單位進行棧內存分配,函數棧幀,局 部變量,形參變量等都存放在棧內存上。堆內存是由用戶自己分配的,C 語言用 malloc/free 進行分配釋放,C++用 new/delete 進行分配釋放,由於堆需要用戶自己管理,因此堆內存 很容易造成內存泄露,而棧內存不會。
- 棧的內存分配釋放速度快效率高,內存都是連續的;堆內存的分配釋放相對於棧來 說效率低一些,內存不一定連續,容易產生內存碎片,但是靈活性高。
- 棧是由高地址向低地址擴展的連續內存,棧的大小一般爲 2M 或者 10M(大家的 redhat 系統可以用 ulimit -s 命令來查看,是 10M);堆是由低地址向高地址擴展的非連續內 存,堆的大小影響的因素比較多,和系統虛擬內存的大小有關係。
看到其他總結的比較好的博客
https://blog.csdn.net/qq_21842557/article/details/50777199
http://blog.csdn.net/FreeeLinux/article/details/53782986