1. 程式人生 > >簡述C語言動態、靜態記憶體分配

簡述C語言動態、靜態記憶體分配

#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釋放記憶體。動態記憶體
的生存期有程式設計師決定,使用非常靈活,但問題也最多。