這個星期我大部分精力都花在了啃指針上。這篇文章對指針中動態內存分配方面做了簡單介紹
一,計算機內存的類型:
這張圖中,內存大體被分為4個部分,code部分是用來儲存程序的指令,static部分是用於儲存靜態變量和全局變量的,而stack也就是棧,在我的理解下,棧是用來儲存函數的,函數從棧頂向下執行,每一個函數被分為一個個的棧幀,在函數執行完之后,棧幀會給自動刪除。我覺得棧和heap也就是堆最大的區別就是,堆是一個我們可以自由分配的內存空間,我們可以根據需要來在堆中開辟內存(前提是不超過系統本身的設置)。而堆的內存是有限的,如果函數使用不當發生無限遞歸可能會導致棧溢出。所以堆就是后面動態內存分配的主角。
二,怎么進行分配和三個進行內存分配的函數
在棧中定義一個指針變量,讓這個使用動態內存分配的函數在堆上開辟一個空間,讓這個指針變量指向這塊內存的首地址。
后面說一下進行內存分配的三個函數 malloc calloc realloc:
malloc:下面是使用的形式
int *p; p = (int*)malloc(n*sizeof(int));
因為malloc只是開辟內存,這個內存可以拿來儲存字符,整形,沒有限制,所以要在malloc前面加上一個類型轉換。malloc括號中就是開辟內存的大小。
calloc:下面是使用的形式
int*p; p = (int*)calloc(n,sizeof(int));
calloc和malloc似乎是一樣的但是還是有不同的,第一個就是使用形式上的不同,malloc直接在后面加上所需內存的大小,而calloc后面的兩個參數分別是幾個內存單位,已經每一個內存單位的大小(不知道這樣說准不准確)。第二個就是初始化的問題,malloc開辟內存的同時若沒有進行初始化,分配出的內存就是一片隨機值。但是calloc所開辟出來的內存會被初始化為0。
realloc:
int *p; p = (int*)malloc(n*sizeof(int)); int *p0; p0 = (inr*)realloc(p,2*n*sizeof(int));
這個函數可以讓內存空間翻倍或者減半。使用形式 realloc(原內存塊,新內存塊大小)。系統會申請一塊新的內存塊大小,然后把原內存塊的內容復制到新內存塊的位置,然后釋放原內存塊的內存。但是新塊的內存要大於原來塊的內存。如果兩個內存塊有連接的部分,則將兩個內存塊連接起來。
realloc還有一些其他應用如:
int *b = (int*)realloc(NULL,n*sizeof(int));
這個代碼就相當與malloc。相當於在內存中分配一些空間。
三 ,釋放內存:
一旦分配完內存之后,堆不像棧,會自動刪除內存,所以需要我們手動釋放內存,我們可以根據我們的需要在任何時候都可以釋放內存。當然不釋放內存,在很多情況下是不會出錯,但是有內存泄漏的風險。
釋放的方法就是用free函數進行釋放。