局部變量分配在棧中,該區域在windows平臺默認爲1M,
動態分配的內存在堆中,該區域非常大,在windows平臺默認大於1.2G
使用動態內存的情況:1.需要通過變量定義數組 2.需要定義大容量的數組
創建動態內存:對內存的動態分配及釋放時通過系統提供的庫函數來實現的,主要有malloc,calloc,realloc,free這四個函數
怎樣建立內存的動態分配:
1.malloc:函數原型 void *malloc(unsigned int size);
在內存的動態存儲區中分配一個長度爲size字節的連續空間 返回值爲: 成功時:動態內存的首地址 失敗時:NULL
malloc(100) 申請100字節的動態內存,注意函數的返回值爲void *,即不指向任何特定類型的數據,只提供一個地址
如果此函數未能成功的執行(例如內存空間不足),則返回空指針(NULL)
2.calloc函數:其函數原型爲void *calloc(unsigned n,unsigned size);
該函數會將內存的所有字節初始化爲0,該函數完全可以被malloc替代
3.realloc:其函數原型爲void *realloc(void *p,unsigned int size);
調整原申請的動態內存的大小,P是原動態內存的地址,size新的內存大小,以字節爲單位。
必須接收新的返回值。
4.free函數:其函數原型爲:void free(void *p);
釋放指針變量p所指向的動態內存,
思考:爲什麼free函數不需要長度信息???參考:https://blog.csdn.net/caogenwangbaoqiang/article/details/79834150
申請內存塊的時候,會有一種機制去記錄內存塊的大小,各個編譯器的做法可能不同,比如申請的時候多分配4個字節,用來存儲整個內存塊的大小。所以在free()的時候只需要傳指針,不需要傳大小。
free釋放的是指向指針的內存,內存!!!不是指針!指針是一個變量,在程序結束時纔會被銷燬,釋放了內存空間後,原來指
向這塊空間的內存還是存在,只不過現在指向的那塊內容是垃圾,是未定義的,所以說是垃圾,
創建內存:
1.都是以字節爲單位,注意乘以sizeof(類型)
2.realloc函數一定要接收返回值,不能使用原地址
free()崩潰的原因:
1.越界 2.移動指針指向 3.重複釋放同一段內存
函數指針:函數的指針 如果在函數中定義了一個函數,在編譯時,編譯系統爲函數代碼分配一段存儲空間,這段存儲空間的起
始地址,稱爲這個函數的指針。
int (* p)(int ,int);
根據優先級p是一個指針,它指向一個函數,這個函數需要兩個整型作爲形參,一個整型作爲返回值。
C語言規定:函數名本身也表示函數的地址,即Max等同&max
那麼p=&max;可以寫成p=Max;
那麼(*p)(10,20);可以寫成p(10,20);
變量和內存:
全局變量:定義在函數外面的變量,儘量少使用。
局部變量:定義在函數內部的變量,包括形參。
static:靜態關鍵字,可以用來修飾全局變量,局部變量(不能修飾形參)和函數。
生命週期 | 作用域 | 默認值 | 內存區域 | 鏈接屬性 | |
靜態全局變量 |
程序運行時創建 程序退出時銷燬 |
整個文件 | 0 | 全局(靜態)變量區 | 內部的 |
普通全局變量 | 程序運行時創建程序退出時銷燬 | 整個文件 | 0 | 全局(靜態)變量區 | 外部的 |
靜態局部變量 | 進入函數時創建程序退出時銷燬 | 函數內部 | 0 | 全局(靜態)變量區 | 無 |
普通局部變量 | 進入函數時創建函數結束時銷燬 | 函數內部 | 隨機值 | 棧 | 無 |
動態內存 | 調用創建函數創建,調用釋放函數銷燬 | 只要能獲取指針的都能用 | 隨機值 | 堆 | 無 |
靜態函數 | 無 | 整個文件 | 無 | 代碼段 | 內部的 |
普通函數 | 無 | 整個文件 | 無 | 代碼段 | 外部的 |
代碼段:存放程序的代碼
全局(靜態)變量區:存放全局變量和靜態變量
棧:存放局部變量,系統自行管理該內存,內存區域小,windows默認1M
堆:動態內存區域,內存區域大,需要由程序自行管理內存,使用後一定要釋放,否則出現內存泄漏。
例:請說明下面的指針分別指向什麼位置:
&p: A ,p: B &p1: C ,p1: C
&p2: C ,p3: D ,p4: C p5: A
void foo(char a)
{
static char nCount;
char p1[]="AAA";
char *p2="AAA";
char *p3=(char *)malloc(10);
char *p4=&a;
char *p5=&nCount;
}
void *p (char)=foo;
A:數據段(全局變量區) B:代碼段 C:棧 D:堆 E:不一定,視調用情況而定