C語言記憶體管理

2021-10-01 23:23:07 字數 3445 閱讀 5140

1、堆:由maloc系列函式或new操作符分配的記憶體。其生命週期由free或delete決定。在沒有釋放之前一直存在,直到程式結束。其特點是使用靈活,空間比較大,但容易出錯。

2、棧:儲存區域性變數。棧上的內容只在函式的範圍內存在,當函式執行結束,這些內容也會自動被銷毀。其特點是效率高,但空間大小有限。

3、靜態區:儲存自動全域性變數和static變數(包括static全域性和區域性變數)。靜態區的內容在整個程式的生命週期內都存在,由編譯器在編譯的時候分配。

#include #include //結構體成員指標未初始化

typedef struct stu ;

int main()

執行**:

能編譯,但是不能執行:

正確方式:

剖析原因:定義的結構體變數stu1,分配了char *型別的指標(指標變數name本身只分配了4個位元組)和int型別的變數score;而nam指標並沒有指向乙個合法的位址。

正確的做法是:為name指標變數malloc一塊空間。

stu1.name = (char *)malloc(10);
注意:分配的記憶體單元一定要大於等於(字串長度+『\0』)

正確**:

#include #include #include //結構體成員指標未初始化

typedef struct stu ;

int main()

執行結果:

沒有為結構體指標分配足夠的記憶體:

#include #include #include //結構體成員指標未初始化

typedef struct stu ;

int main()

程式能編譯,執行結果錯誤:

原因:為pstu分配記憶體的時候,分配的記憶體大小不合適。這裡把sizeof(stu),誤寫為sizeof(stu *)。當然name指標同樣沒有被分配記憶體,解決辦法同上!

pstu = (stu *)malloc(sizeof(stu ));

pstu->name = (char *)malloc(10);

正確程式:

#include #include #include //結構體成員指標未初始化

typedef struct stu ;

int main()

執行結果:

函式原型: void * malloc(int size )

malloc函式的返回值是乙個void型別的指標,引數為int型別資料,即申請分配的記憶體大小,單位是位元組。記憶體分配成功之後,malloc函式返回這塊記憶體的首位址,你需要乙個指標來接收這個位址。但是由於函式的返回值是void * 型別的,所i必須強制轉換成你所接收的型別。也就是說,這塊記憶體將要用來儲存什麼型別的資料,比如:

char *p=(char *)malloc(100);
在堆上分配了100位元組的記憶體,返回這塊記憶體的首位址,把位址強制轉換成char * 型別後賦給char *型別的指標變數p;同時告訴我們這塊記憶體將用來儲存char 型別的資料。也就是說你只能通過指標變數p來操作這塊記憶體。這塊記憶體本身並沒有名字,對它的訪問是匿名訪問。

注意:malloc函式申請的是連續的一塊記憶體。

既然有分配,那就必須有釋放。不然的話,有限的記憶體總會用光,而沒有釋放的記憶體卻在空閒。與malloc對應的就是free函式了。free函式只有乙個引數,就是所要釋放的記憶體快的首位址,接上例則為:

free(p);
free函式看上去挺狠的,但它到底做了什麼呢?

其實它就做了一件事:斬斷指標變數與這塊記憶體的關係。比如上面的例子,我們可以說 malloc 函式分配的記憶體塊是屬於p的,因為我們對這塊記憶體的訪問都需要通過 p 來進行。free 函式就是把這塊記憶體和p之間的所有關係斬斷,從此 p 和那塊記憶體之間再無瓜葛。至於指標變數 p 本身儲存的位址並沒有改變,但是它對這個位址處的那塊記憶體卻已經沒有所有權了。那塊被釋放的記憶體裡面儲存的值也沒有改變,只是再也沒有辦法使用了。

在程式中,malloc和free一定要成對出現,出現次數相等。malloc兩次,free一次,會出現記憶體洩漏;malloc一次,free兩次肯定會出錯。遵循:一夫一妻制!

既然使用 free 函式之後指標變數 p 本身儲存的位址並沒有改變,那我們就需要重新把 p 的值變為null;

p=null;
這個 null 就是我們前面所說的「栓野狗的鍊子」,如果你不栓起來遲早會出問題的。比如:

char *p = (char *)malloc(100);

strcpy(p,"hello");

free(p); //p所指的記憶體被釋放,但是p所指的位址仍然不變

…if (p != null)

釋放完塊記憶體之後,沒有把指標置null,這個指標就成為了「野指標」。這是很危險的,而且也是經常出錯的地方。所以一定要記住一條:free之後,一定要給指標置null。

這裡一般有三種情況:

1、就是上面所說的,free(p)之後,繼續通過p指標來訪問記憶體。解決的辦法就是給 p 置null

2、函式返回棧記憶體,這是初學者最容易犯的錯誤。比如在函式內部定義了乙個陣列,卻用 return 語句返回指向該陣列的指標。解決的辦法就是弄明白棧上變數的生命週期。

3、記憶體使用太複雜,弄不清到底哪塊記憶體被釋放,哪塊沒有被釋放。解決的辦法就是重新設計程式,改善物件之間的呼叫關係。

c語言記憶體管理

在c語言中,根據資料在記憶體中存在的時間 生存期 不同,將記憶體空間分為三個區 1.程式區 用於儲存程式的 即程式的二進位制 存放函式體的二進位制 2.靜態儲存區 用於儲存全域性變數和靜態變數,這些變數的空間在程式編譯時就已經分配好了.全域性變數和靜態變數的儲存是放在一塊的,初始化的全域性變數和靜態...

C語言 記憶體管理

對於任何的作業系統來說,記憶體都是很寶貴的乙個地方。所以,對於程式語言來說,記憶體管理就顯得尤為重要。c語言 在記憶體中執行的時候,我們大致將占用的記憶體分為4塊區域 區 靜態區 棧區 堆區。這4各區域,有著各自的特點,他們也儲存著我們的程式在執行中的不同型別的資料。弄明白了這4個區域的資料儲存特點...

C語言 記憶體管理

記憶體管理一號傳送門 記憶體管理二號傳送門 對於乙個c語言程式而言,記憶體空間主要由五個部分組成 段 text 資料段 data bss段 bss 堆和棧組成,其中 段,資料段和bss段是編譯的時候由編譯器分配的,而堆和棧是程式執行的時候由系統分配的。在上圖中,由編譯器分配的位址空間都是在連線的時候...