C程式之儲存方式與區別

2021-07-30 00:18:33 字數 2174 閱讀 4535

malloc 函式返回的是 void * 型別,如果你寫成:p = malloc (sizeof(int)); 則程式無法通過編譯,報錯:「不能將 void* 賦值給 int * 型別變數」。所以必須通過 (int *) 來將強制轉換。

第二、函式的實參為 sizeof(int) ,用於指明乙個整型資料需要的大小。如果你寫成:

int* p = (int *) malloc (1);

**也能通過編譯,但事實上只分配了1個位元組大小的記憶體空間,當你往裡頭存入乙個整數,就會有3個位元組無家可歸,而直接「住進鄰居家」!造成的結果是後面的記憶體中原有資料內容全部被清空。

malloc 也可以達到 new 的效果,申請出一段連續的記憶體,方法無非是指定你所需要記憶體大小。

比如想分配100個int型別的空間:

int* p = (int *) malloc ( sizeof(int) * 100 ); //分配可以放得下100個整數的記憶體空間。

3、關於函式使用需要注意的一些地方:

a、申請了記憶體空間後,必須檢查是否分配成功。 

b、當不需要再使用申請的記憶體時,記得釋放;釋放後應該把指向這塊記憶體的指標指向null,防止程式後面不小心使用了它。 

c、這兩個函式應該是配對。如果申請後不釋放就是記憶體洩露;如果無故釋放那就是什麼也沒有做。釋放只能一次,如果釋放兩次及兩次以上會 

出現錯誤(釋放空指標例外,釋放空指標其實也等於啥也沒做,所以釋放空指標釋放多少次都沒有問題)。 

d、雖然malloc()函式的型別是(void *),任何型別的指標都可以轉換成(void *),但是最好還是在前面進行強制型別轉換,因為這樣可以躲過一些編譯器的檢查。 

好了!最基礎的東西大概這麼說!現在進入第二部分: 

malloc()到底從**得來了記憶體空間? 

1、malloc()到底從**得到了記憶體空間?答案是從堆裡面獲得空間。也就是說函式返回的指標是指向堆裡面的一塊記憶體。作業系統中有乙個記錄空閒記憶體位址的鍊錶。當作業系統收到程式的申請時,就會遍歷該鍊錶,然後就尋找第乙個空間大於所申請空間的堆結點,然後就將該結點從空閒結點鍊錶中刪除,並將該結點的空間分配給程式。就是這樣! 

說到這裡,不得不另外插入乙個小話題,相信大家也知道是什麼話題了。什麼是堆?說到堆,又忍不住說到了棧!什麼是棧?下面就另外開個小部分專門而又簡單地說一下這個題外話: 

2、什麼是堆

:堆是大家共有的空間,分全域性堆和區域性堆。全域性堆就是所有沒有分配的空間,區域性堆就是使用者分配的空間。堆在作業系統對程序 初始化的時候分配,執行過程中也可以向系統要額外的堆,但是記得用完了要還給作業系統,要不然就是記憶體洩漏。 

什麼是棧

記憶體分配方式以及它們的區別?

1) 從靜態儲存區域分配。內存在程式編譯的時候就已經分配好,這塊內存在程式的整個執行期間都存在。例如全域性變數,static 變數。 2) 在棧上建立。在執行函式時,函式內區域性變數的儲存單元都可以在棧上建立,函式執行結束時這些儲存單元自動被釋放。棧記憶體分配運算內置於處理器的指令集。 3) 從堆上分配,亦稱動態記憶體分配。程式在執行的時候用malloc 或new 申請任意多少的記憶體,程式設計師自己負責在何時用free 或delete 釋放記憶體。動態記憶體的生存期由程式設計師決定,使用非常靈活,但問題也最多。

動態記憶體分配?

就是指在程式執行的過程中動態地分配或者**儲存空間的分配記憶體的方法。動態記憶體分配不象陣列等靜態記憶體分配方法那樣需要預先分配儲存空間,而是由系統根據程式的需要即時分配,且分配的大小就是程式要求的大小。

例如我們定義乙個float型陣列:float score[100]; 

但是,在使用陣列的時候,總有乙個問題困擾著我們:陣列應該有多大?在很多的情況下,你並不能確定要使用多大的陣列,比如上例,你可能並不知道我們要定義的這個陣列到底有多大,那麼你就要把陣列定義得足夠大。這樣,你的程式在執行時就申請了固定大小的你認為足夠大的記憶體空間。即使你知道你想利用的空間大小,但是如果因為某種特殊原因空間利用的大小有增加或者減少,你又必須重新去修改程式,擴大陣列的儲存範圍。這種分配固定大小的記憶體分配方法稱之為靜態記憶體分配。但是這種記憶體分配的方法存在比較嚴重的缺陷,特別是處理某些問題時:在大多數情況下會浪費大量的記憶體空間,在少數情況下,當你定義的陣列不夠大時,可能引起下標越界錯誤,甚至導致嚴重後果。 

我們用動態記憶體分配就可以解決上面的問題. 所謂動態記憶體分配就是指在程式執行的過程中動態地分配或者**儲存空間的分配記憶體的方法。動態記憶體分配不象陣列等靜態記憶體分配方法那樣需要預先分配儲存空間,而是由系統根據程式的需要即時分配,且分配的大小就是程式要求的大小。

C 動態儲存方式與靜態儲存方式

如果從變數值存在的時間 即生存期 來分,可將程式中的變數分為 動態儲存方式和靜態儲存方式。它們所占用的儲存空間區域不同。區 存放可執行程式的程式 靜態儲存區 存放靜態變數和全域性變數。棧區 stack 存放動態區域性變數 堆區 heap 存放new和 malloc 申請的動態記憶體。棧區和堆區統稱為...

C 儲存方式

今天,莫名其妙地 奮奮 看著一本c 的時候,突然想到,是不是可以用陣列越界來 一下,c 的儲存方式呢?由於書頁上的內容太多。就簡單地寫寫吧。int main const int size 4 float a size for int i 0 i 7 i cout ta i a i endl syst...

C 與matlab儲存方式的不同

注意到 c 矩陣的資料是按 行優先 進行儲存的 matlab矩陣的資料是按 列優先 進行儲存的 在c 中矩陣元素下標常這樣來查詢 假設其第 item id 個 2 維矩陣,該矩陣的 高為 data height,寬為 data width.index item id data height h da...