先說一下c語言中的記憶體管理。
1.動態記憶體分配
①原因:程式執行過程中,很有可能需要一些額外的記憶體空間。
②動態記憶體從**來,還給誰?
這塊是記憶體是系統專門預留出來的,給程式動態的分配和動態的歸還的。
當free函式的引數為空的時候,那麼我們的free什麼事都不做了。
clloc和realloc的用法見截圖:
動態記憶體是從堆上分配空間的,具體形式以int為例 int *a = (int*)malloc (5*(sizeof(int)))。
2.棧,堆,靜態儲存區
①沒有棧就沒有函式,就沒有區域性變數。函式是依賴於棧的存在而存在的。
這個棧不是資料結構中的棧,是記憶體棧。
後進先出的原則沒有改變。
每乙個函式的呼叫在記憶體中都會產生活動記錄,這個活動記錄包括函式的引數和返回位址等等,所以可以說這個活動記錄就是在棧上面建立的。
按照老唐的話說,乙個棧應該包含的有如下資料
(1)返回位址(子函式ebp在返回ebp的時候應該指向的位置)
(2)old ebp
(3)資料(包含函式中的所有資料)(這也是子函式和子函式esp指向的位置)
棧的增長方式:從棧底一直向上增長。
②因為棧的資料在函式執行結束之後就會被釋放了,沒有傳遞到函式的外部,所以產生了程式中的堆。
堆中申請的內存在程式主動釋放前一直有效。堆空間就是為了動態記憶體分配而產生的。
堆空間必須要通過申請才可以得到。
堆管理的方法有很多。老唐講的鍊錶法很清晰。
③程式靜態儲存區
程式靜態儲存區在程式執行的時候就已經開闢出來了,同時在程式執行結束的時候釋放。
靜態程式區的大小在程式編譯的時候就已經規定好了。
程式的靜態儲存區主要用於儲存程式執行的全域性變數和靜態變數。
這三個儲存區是程式中所用的絕大數區域。
3.程式的記憶體布局。
程式中除了棧,堆,靜態儲存區以外還有其他的儲存區麼?
可執行程式的布局:
(1)可執行程式的檔案頭:作業系統來讀這個可執行程式的檔案頭,看一下這個檔案頭里的資訊是不是系統想要的資訊。
(2).text段,這裡面儲存的是主函式和子函式的執行內容。
(3).data段,這裡面儲存的是申請並且賦值的全域性變數,以及申請並且賦值的靜態變數。
(4).bss段,這裡面儲存的是申請但是沒有賦值的全域性變數,以及申請並沒有賦值的靜態變數。
通過上面的四個段,沒有找到儲存申請並且賦值的區域性變數的地方也沒有申請但是沒有賦值的區域性變數的地方。因為區域性變數是儲存在棧空間中的。
程式檔案的布局是程式可執行檔案的布局,並不是程式執行過程中的布局,堆疊和靜態儲存區才是程式執行過程(程序)的布局。
text段、data段和bss段在程式執行的時候(程序)會被對映到程序空間中。
棧和堆是要等到程式執行之後由作業系統進行分配的。
這裡的棧可以理解成為乙個彈性的東西,所以在程式執行的時候對映過來的段和隨著棧的行為來行動。
靜態儲存區在程式編譯的時候就已經開始分配空間了,所以靜態儲存區在程式執行的時候依然可以對應一部分程式的可執行檔案的空間。函式的位址對應的是程式text段中的某個位址。
4.野指標通常是因為指標變數儲存的值不是乙個合法記憶體位址造成的。
在c中沒有任何手段來判別乙個指標是否是野指標。
①區域性指標變數沒有被初始化。
#include struct student
; int main()
解決辦法:
#include #include struct student
; int main()
上面程式少了乙個free(s.name).
②指標釋放後程式就歸還了這片空間,既然歸還了那麼就不可以再使用這篇空間了。
使用已經釋放後的指標。
例程:
#include #include #include int f(char*i)
int main()
解決辦法:
#include #include #include int f(char*i)
int main()
③指標所指向的變數在指標之前被銷毀。
5.記憶體操作中的經典錯誤
①非法記憶體操作
②記憶體分配成功但是並沒有初始化
例程;
#include int main()
③陣列越界
④記憶體洩露
⑤多次釋放指標----誰申請誰釋放。
⑥使用已經釋放的記憶體。
6.老唐自己的交通規則
①使用malloc之後應該立刻判斷返回值是否為空。可以杜絕操作0位址裡面的內容,這個位址是為作業系統使用的。
例程:
#includeint main()
free (p);
return 0;
}
②牢記陣列長度,防止越界操作。----使用柔性陣列。
③動態申請的操作必須和釋放操作相匹配。
④free指標以後,被free的指標要賦值為空。
C語言中記憶體管理規範
一 記憶體申請 1.建議使用calloc申請記憶體,盡量不要使用malloc。calloc在動態分配完記憶體後,自動初始化該記憶體空間為零,而malloc不初始化,裡邊資料是隨機的垃圾資料。2.申請記憶體大小必須大於0.1 使用0位元組長度申請記憶體的行為是沒有定義的,在引用記憶體申請函式返回位址時...
c語言中的動態記憶體管理
malloc calloc realloc的區別與聯絡 在c語言 c 中和記憶體申請與釋放的相關函式有 alloc malloc calloc realloc free.1 alloc是在棧上申請空間,無需使用者主動釋放,當函式執行結束時,在棧上分配的記憶體會被自動釋放,棧記憶體分配運算內置於處理器...
c語言中的動態記憶體管理
malloc通常用來開闢一段連續記憶體空間 void malloc size t size 1 如果記憶體開闢成功,則返回乙個指向開闢好空間的指標 2 如果開闢失敗,則返回乙個null指標,因此malloc的返回結果必須判空 3 由於返回值型別為void 具體使用時根據自身需要強制型別轉換 4 如果...