記憶體管理
動態分配記憶體
重新調整記憶體的大小和釋放記憶體
malloc 函式詳解
memset 初始化記憶體資料
《程式編譯流程與 gcc 編譯器》
《c 語言程式設計 — 基本語法》
《c 語言程式設計 — 基本資料型別》
《c 語言程式設計 — 變數與常量》
《c 語言程式設計 — 運算子》
《c 語言程式設計 — 邏輯控制語句》
《c 語言程式設計 — 函式》
《c 語言程式設計 — 高階資料型別 — 指標》
《c 語言程式設計 — 高階資料型別 — 陣列》
《c 語言程式設計 — 高階資料型別 — 字串》
《c 語言程式設計 — 高階資料型別 — 列舉》
《c 語言程式設計 — 高階資料型別 — 結構體與位域》
《c 語言程式設計 — 高階資料型別 — 共用體》
《c 語言程式設計 — 高階資料型別 — void 型別》
《c 語言程式設計 — 資料型別的別名》
《c 語言程式設計 — 資料型別轉換》
《c 語言程式設計 — 巨集定義與預處理器指令》
《c 語言程式設計 — 異常處理》
《c 語言程式設計 — 標頭檔案》
《c 語言程式設計 — 輸入/輸出與檔案操作》
c 語言的設計者把記憶體簡單粗暴地想象成乙個巨大的位元組(byte)陣列。事實上,它被更加合理地劃分成了兩部分,即棧和堆。實際上,它們只是記憶體中的兩塊不同的區域,分別用來完成不同的任務而已。
棧是程式賴以生存的地方,所有的臨時變數和資料結構都儲存於其中,供你讀取及編輯。每次呼叫乙個新的函式,就會有一塊新的棧區壓入,並在其中存放函式內的臨時變數、傳入的實參的拷貝以及其它的一些資訊。當函式執行完畢,這塊棧區就會被彈出並**,供其他函式使用。
堆佔據另一部分記憶體,主要用來存放長生命週期期的資料。堆中的資料必須手動申請和釋放。
申請記憶體使用 malloc 函式。這個函式接受乙個數字作為要申請的位元組數,返回申請好的記憶體塊的指標。當使用完畢申請的記憶體,我們還需要將其釋放,只要將 malloc 函式返回的指標傳給 free 函式即可。
堆比棧的使用難度要大一些,因為它要求程式設計師手動呼叫 free 函式釋放記憶體,而且還要正確呼叫。如果不釋放,程式就有可能不斷申請新的記憶體,而不釋放舊的,導致記憶體越用越多。這也被稱為記憶體洩漏。避免這種情況發生的乙個簡單有效的辦法就是,針對每乙個 malloc 函式呼叫,都有且只有乙個 free 函式與之對應。這某種程度上就能保證程式能正確處理堆記憶體的使用。
我把堆想象成乙個自助儲存倉庫,我們使用 malloc 函式申請儲存空間。我們可以在自主儲存倉庫和建築工地之間自由訪問。它非常適合用來存放大件的偶爾才用一次的物件。唯一的問題就是在用完之後要記得使用 free 函式將空間歸還。
c 語言為記憶體的分配和管理提供了幾個標準函式。這些函式可以在 stdlib.h 標頭檔案中找到。
注:void *
型別表示未確定型別的指標。c、c++ 規定void *
型別可以通過強制型別轉換為任何其它型別的指標。
#include
#include
#include
intmain()
else
printf
("name = %s\n"
, name)
;printf
("description: %s\n"
, description)
;return0;
}
執行:
$ ./main
name = zara ali
description: zara ali a dps student in class 10th
上面的程式也可以使用calloc()
函式來編寫,只需要把 malloc 替換為 calloc 即可:
calloc
(200
,sizeof
(char))
;
當動態分配記憶體時,程式有完全控制權,可以傳遞任何大小的值。不同的是,那些預先定義了大小的陣列,一旦定義則無法改變大小。
當程式退出時,作業系統會自動釋放所有分配給程式的記憶體,但是主動釋放記憶體是乙個良好的程式設計習慣。
#include
#include
#include
intmain()
else
/* 擴充套件分配記憶體,記憶體大小為 100 個字元長度(8 bit)。
函式呼叫返回記憶體的指標(位址)並強制型別轉換為字元指標型別。
*/description =
(char*)
realloc
(description,
100*
sizeof
(char))
;if(description ==
null
)else
printf
("name = %s\n"
, name)
;printf
("description: %s\n"
, description)
;/* 釋放記憶體 */
free
(description)
;return0;
}
執行:
$ ./main
name = zara ali
description: zara ali a dps student in class 10th
she is in class 10th
函式原型:
void
*malloc
(size_t size)
;
int
*p;p =
(int*)
malloc
(sizeof
(int))
;
簡而言之,malloc 函式其實就是在記憶體中找到一片指定大小的、邏輯連續的記憶體空間,然後將這個空間的首位址給乙個指標變數,這裡的指標變數可以是乙個單獨的指標,也可以是乙個陣列的首位址,具體要看 size_t size 實參的具體內容。
int
*arr;
arr =
(int*)
malloc
(sizeof
(int)*
10);
在 c 語言程式設計匯中應該要保持乙個習慣:定義變數時一定要進行初始化,尤其是陣列和結構體這種占用記憶體大的資料結構。因為在使用陣列或分配記憶體時,程式得到的只是乙個記憶體空間的位址,實際上記憶體空間的值並非一直是 「乾淨」 的,在沒有初始化的情況下,經常會因為髒資料而產生亂碼。
c 語言中,每種資料型別的變數都有各自的初始化方法,為 memset 函式可以說是初始化記憶體的萬能函式,作用是在一段記憶體塊中填充某個給定的值,通常用於為新申請的記憶體或陣列進行初始化工作。
函式原型:將指標變數 s 所指向的前 n 位元組的記憶體單元用乙個 int 型別 c(通常為 0)替換。其中,n 通常是使用 sizeof 獲取的,因為 s 是 void* 型的指標變數,所以它可以為任何型別的資料進行初始化。用 memset 初始化完後,後續的**中再向該記憶體空間中存放預期的資料。
#include
void
*memset
(void
*s,int c,
unsigned
long n)
;
示例:
#include
#include
intmain
(void
)printf
("\n");
return0;
}
C 堆 棧與記憶體管理
一 所謂stack和heap 例子 class complex 作用域 scope stack 儲存區域性變數或臨時物件的一塊記憶體,函式呼叫結束會消失 heap 存放全域性物件或變數的記憶體空間,函式呼叫結束如果不通過delete 釋放將直到程式執行結束之前一直存在。二 static local ...
C 侯捷 堆 棧與記憶體管理
class complex complex c3 1,2 void main stack棧 是存在於魔偶作用域的一塊記憶體空間,函式本身會形成乙個stack,存放接收的引數和返回位址以及local object。c1所用的空間來自stack。器生命在作用域之內有效,會自動清理,析構函式自動呼叫。st...
c語言記憶體管理
在c語言中,根據資料在記憶體中存在的時間 生存期 不同,將記憶體空間分為三個區 1.程式區 用於儲存程式的 即程式的二進位制 存放函式體的二進位制 2.靜態儲存區 用於儲存全域性變數和靜態變數,這些變數的空間在程式編譯時就已經分配好了.全域性變數和靜態變數的儲存是放在一塊的,初始化的全域性變數和靜態...