C語言學習筆記 動態記憶體分配

2021-07-03 18:32:28 字數 2596 閱讀 7606

記憶體分割槽

說明

程式**區(code area)

存放函式體的二進位制**

靜態資料區(data area)

也稱全域性資料區,包含的資料型別比較多,如全域性變數、靜態變數、一般常量、字串常量。其中:

注意:靜態資料區的內存在程式結束後由作業系統釋放。

堆區(heap area)

一般由程式設計師分配和釋放,若程式設計師不釋放,程式執行結束時由作業系統**。

malloc()

、calloc()

、free()

等函式操作的就是這塊記憶體,這也是本章要講解的重點。

注意:這裡所說的堆區與資料結構中的堆不是乙個概念,堆區的分配方式倒是類似於鍊錶。

棧區(stack area)

由系統自動分配釋放,存放函式的引數值、區域性變數的值等。其操作方式類似於資料結構中的棧。

命令列引數區

存放命令列引數和環境變數的值,如通過main()函式傳遞的值。

注意:每個記憶體分配函式必須有相應的 free 函式,釋放後不能再次使用被釋放的記憶體,建議在 free 函式後把被釋放指標置為 null,好處有二:

注: 雖然為了與c語言相容,c++仍保留malloc和free函式,但建議使用者不用malloc和free函式,而用new和delete運算子。new和delete是運算子,不是函式,因此執行效率高。

new運算子使用的一般格式為:

new 型別 (初值);

用new分配陣列空間時不能指定初值。如果由於記憶體不足等原因而無法正常分配空間,則new會返回乙個空指標null,使用者可以根據該指標的值判斷分配空間是否成功。

delete運算子使用的一般格式為:

delete [ ] 指標變數

有些時候,常常會有將記憶體丟失的情況,例如:

int *pold = (int*) malloc( sizeof(int) );

int *pnew = (int*) malloc( sizeof(int) );

這兩段**分別建立了一塊記憶體,並且將記憶體的位址傳給了指標 pold 和 pnew。此時指標 pold 和 pnew 分別指向兩塊記憶體。

如果接下來進行這樣的操作:

pold=pnew;
free(pold);
此時釋放的 pold 所指向的記憶體空間就是原來 pnew 指向的,於是這塊空間被釋放掉了。但是 pold 原來指向的那塊記憶體空間還沒有被釋放,不過因為沒有指標指向這塊記憶體,所以這塊記憶體就造成了丟失。

另外,你不應該進行類似這面這樣的操作:

malloc( sizeof(int) );
這樣的操作沒有意義,因為沒有指標指向分配的記憶體,無法使用,而且無法通過 free() 釋放掉,造成了記憶體洩露。

預設即auto型別

1.在所有的**塊(函式、if 塊、switch 塊等)之外定義的變數稱為全域性變數,它的作用範圍預設是整個程式,

也就是所有的原始檔,包括 .c 和 .h 檔案。

2.雖然全域性變數的作用範圍是整個程式,但是如果希望在 a.c 中使用 b.c 中的變數,也必須先進行宣告。宣告

使用 extern 關鍵字

3.extern 變數的定義格式為:

extern type name = value;
宣告格式為:
extern type name;
4.extern 可以省略(我們通常就是這麼做的),全域性變數預設就是 extern 的

5.extern 變數的作用域跟它的宣告位置有關,在**塊內宣告的 extern 變數在**塊外無效。

6.函式和變數的宣告有所不同,對於函式,你可以省略 extern

1.實際開發中我們一般將不需要被其他檔案呼叫的全域性變數或函式的作用範圍限制在當前檔案中,

可以通過 static 關鍵字來限制

2.static 宣告的變數稱為

靜態變數

,不管是全域性變數還是區域性變數,都儲存在靜態資料區(全域性變數本來就儲存在靜態資料區,即使不加 static)。

靜態資料區的資料在程式啟動時就會初始化,直到程式執行結束;對於**塊中的靜態區域性變數,即使**塊執行結束,也不會銷毀。

注意:靜態資料區的變數只能初始化(定義)一次,以後只能改變它的值,不能再被初始化,即使有這樣的語句,也無效。

3.1.可以將使用頻繁的變數放在cpu的通用暫存器中,暫存器的數量是有限的,通常是把使用最頻繁的變數定義為 register 的。

2.關於暫存器變數有以下事項需要注意:

1) 為暫存器變數分配暫存器是動態完成的,因此,只有區域性變數和形式引數才能定義為暫存器變數。

2) 區域性靜態變數不能定義為暫存器變數,因為乙個變數只能宣告為一種儲存類別。

3) 暫存器的長度一般和機器的字長一致,所以,只有較短的型別如int、char、short等才適合定義為暫存器變數,諸如double等較大的型別,不推薦將其定義為暫存器型別。

4) cpu的暫存器數目有限,因此,即使定義了暫存器變數,編譯器可能並不真正為其分配暫存器,而是將其當做普通的auto變數來對待,為其分配棧記憶體。當然,有些優秀的編譯器,能自動識別使用頻繁的變數,如迴圈控制變數等,在有可用的暫存器時,即使沒有使用 register 關鍵字,也自動為其分配暫存器,無須由程式設計師來指定。

C語言學習筆記 動態記憶體分配

1 c 語言中的一切操作都是基於記憶體的。2 變數和陣列都是記憶體的別名。記憶體分配由編譯器在編譯期間決定 定義陣列的時候必須指定陣列長度 陣列長度是在編譯期就必須確定的 3 但是程式執行的過程中,可能需要使用一些額外的記憶體空間 1 malloc 和 free 用於執行動態記憶體分配的釋放 2 m...

c語言動態記憶體分配 C 動態記憶體分配

動態記憶體分配 雖然通過陣列就可以對大量的資料和物件進行有效地管理,但是很多情況下,在程式執行之前,我們並不能確切地知道陣列中會有多少個元素。這種情況下,如果陣列宣告過大,就會造成浪費 宣告過小,就會影響處理。在c 中,動態記憶體分配技術可以保證程式在執行過程中按照需要申請適量記憶體,使用後釋放,從...

C語言動態記憶體分配

c語言動態記憶體分配 動態資料結構可以在執行時靈活新增 刪除或重排資料項。在執行時分配記憶體空間的過程稱為動態記憶體分配。記憶體分配函式如下 malloc 分配所需的位元組大小,並返回指向所分配空間的第乙個位元組的指標 calloc 為元素陣列分配空間,並初始化為零,然後返回指向該記憶體的指標 fr...