簡述C語言動態、靜態記憶體分配
阿新 • • 發佈:2019-01-06
#include <stdio.h> #include <stdlib.h> /** c語言靜態記憶體分配 */ void func(int** address ) { //定義int型別的i變數,並賦值100 int i = 100; //把i對應的地址賦值給iPoint變數 *address = &i; } int main(int argc, char *argv[]) { //定義int型別的一級指標變數iPoint int* iPoint; func(&iPoint); printf("*iPoint==%d\n",*iPooint); //列印值為100 printf("*iPoint==%d\n",*iPooint); //列印值為-2 (變為垃圾值) system("pause"); return 0; } 原因:靜態記憶體是程式編譯執行後系統自動分配,由系統自動釋放,靜態記憶體是棧分配的。在我們執行完func方法後,系統會在不確定的時間回收記憶體, 當再次去呼叫時,若被系統回收,則無法取到對應地址的值。 具體執行過程如下圖:
當呼叫func方法時,會建立func函式,並將iPoint的地址存入address的二級指標中,*address = &i 語句執行時,是將i變數的地址 存入address對應的1000H地址中,當列印*iPooint時會取3000H地址對應的值100,當func被系統回收後,再取值會取不到值。 /** c語言動態記憶體分配 */ void func(int** address ) { int i = 100; int* temp; //malloc(int) --記憶體地址 此方法返回的是記憶體地址 temp = malloc(sizeof(int)); //把i對應的值,賦值給temp地址對應的值 *temp = i; //把address對應的地址對應的值修改成temp *address = temp; //free(temp); //釋放記憶體 } int main(int argc, char *argv[]) { //定義int型別的一級指標變數iPoint int* iPoint; func(&iPoint); printf("*iPoint==%d\n",*iPooint); //列印值為100 printf("*iPoint==%d\n",*iPooint); //列印值為100 (記憶體沒有被回收) system("pause"); return 0; } 動態記憶體是開發者手動去分配的,是堆分配的。 具體執行過程如下圖:
當呼叫func方法時,會建立func函式,並將iPoint的地址存入address的二級指標中,接下來建立int變數i,值為100,建立temp一級指標,在堆內申請一塊 記憶體,並將地址存入temp地址所對應的值中,*temp = i語句執行後,將temp對應的5000H對應的值修改為100,*address = temp語句是將temp中的5000H寫 入address對應的地址值中。當列印*iPooint時,會通過地址5000H去堆記憶體去取,即使func被系統回收也不影響。 記憶體分配方式: (1) 從靜態儲存區域分配。記憶體在程式編譯的時候就已經分配好,這塊記憶體在程式的整個執行期間都存在。例如全域性變數,static變數。 (2) 在棧上建立。在執行函式時,函式內部區域性變數的儲存單元都可以在棧上建立,函式執行結束時這些儲存單元自動被釋放,棧記憶體分配運算內置於處理 器的指令集中,效率很高,但是分配的記憶體容量有限。 (3) 從堆上分配。亦稱動態記憶體分配。程式在執行的時候用malloc或new申請任意多的記憶體,程式設計師自己負責在什麼時候free或delete釋放記憶體。動態記憶體 的生存期有程式設計師決定,使用非常靈活,但問題也最多。