1. 程式人生 > >C語言記憶體管理(林銳博士的文章)

C語言記憶體管理(林銳博士的文章)

7.1記憶體分配方式 
記憶體分配方式有三種: 
(1)       從靜態儲存區域分配。記憶體在程式編譯的時候就已經分配好,這塊記憶體在程式的整個執行期間都存在。例如全域性變數,static變數。 
(2)       在棧上建立。在執行函式時,函式內區域性變數的儲存單元都可以在棧上建立,函式執行結束時這些儲存單元自動被釋放。棧記憶體分配運算內置於處理器的指令集中,效率很高,但是分配的記憶體容量有限。 
(3)       從堆上分配,亦稱動態記憶體分配。程式在執行的時候用malloc或new申請任意多少的記憶體,程式設計師自己負責在何時用free或delete釋放記憶體。動態記憶體的生存期由我們決定,使用非常靈活,但問題也最多。 
7.2常見的記憶體錯誤及其對策 
       發生記憶體錯誤是件非常麻煩的事情。編譯器不能自動發現這些錯誤,通常是在程式執行時才能捕捉到。而這些錯誤大多沒有明顯的症狀,時隱時現,增加了改錯的難度。有時使用者怒氣衝衝地把你找來,程式卻沒有發生任何問題,你一走,錯誤又發作了。 
常見的記憶體錯誤及其對策如下: 
u       記憶體分配未成功,卻使用了它。 
程式設計新手常犯這種錯誤,因為他們沒有意識到記憶體分配會不成功。常用解決辦法是,在使用記憶體之前檢查指標是否為NULL。如果指標p是函式的引數,那麼在函式的入口處用assert(p!=NULL)進行檢查。如果是用malloc或new來申請記憶體,應該用if(p==NULL) 或if(p!=NULL)進行防錯處理。 

u       記憶體分配雖然成功,但是尚未初始化就引用它。 
犯這種錯誤主要有兩個起因:一是沒有初始化的觀念;二是誤以為記憶體的預設初值全為零,導致引用初值錯誤(例如陣列)。 
記憶體的預設初值究竟是什麼並沒有統一的標準,儘管有些時候為零值,我們寧可信其無不可信其有。所以無論用何種方式建立陣列,都別忘了賦初值,即便是賦零值也不可省略,不要嫌麻煩。 

u       記憶體分配成功並且已經初始化,但操作越過了記憶體的邊界。 
例如在使用陣列時經常發生下標“多1”或者“少1”的操作。特別是在for迴圈語句中,迴圈次數很容易搞錯,導致陣列操作越界。 

u       忘記了釋放記憶體,造成記憶體洩露。 
含有這種錯誤的函式每被呼叫一次就丟失一塊記憶體。剛開始時系統的記憶體充足,你看不到錯誤。終有一次程式突然死掉,系統出現提示:記憶體耗盡。 
動態記憶體的申請與釋放必須配對,程式中malloc與free的使用次數一定要相同,否則肯定有錯誤(new/delete同理)。 
u       釋放了記憶體卻繼續使用它。 
有三種情況: 
(1)程式中的物件呼叫關係過於複雜,實在難以搞清楚某個物件究竟是否已經釋放了記憶體,此時應該重新設計資料結構,從根本上解決物件管理的混亂局面。 
(2)函式的return語句寫錯了,注意不要返回指向“棧記憶體”的“指標”或者“引用”,因為該記憶體在函式體結束時被自動銷燬。 
(3)使用free或delete釋放了記憶體後,沒有將指標設定為NULL。導致產生“野指標”。 

l         【規則7-2-1】用malloc或new申請記憶體之後,應該立即檢查指標值是否為NULL。防止使用指標值為NULL的記憶體。 
l         【規則7-2-2】不要忘記為陣列和動態記憶體賦初值。防止將未被初始化的記憶體作為右值使用。 
l         【規則7-2-3】避免陣列或指標的下標越界,特別要當心發生“多1”或者“少1”操作。 
l         【規則7-2-4】動態記憶體的申請與釋放必須配對,防止記憶體洩漏。 
l         【規則7-2-5】用free或delete釋放了記憶體之後,立即將指標設定為NULL,防止產生“野指標”。 

相關推薦

C語言記憶體管理(博士文章)

7.1記憶體分配方式  記憶體分配方式有三種:  (1)       從靜態儲存區域分配。記憶體在程式編譯的時候就已經分配好,這塊記憶體在程式的整個執行期間都存在。例如全域性變數,static變數。  (2)       在棧上建立。在執行函式時,函式內區域性變數的儲存單元都可以在棧上建立,函式執行結束時這些

C語言記憶體管理

記憶體管理的基本概念 分析C語言記憶體的分佈先從Linux下可執行的C程式入手。現在有一個簡單的C源程式hello.c 1 #include <stdio.h> 2 #include <stdlib.h> 3 int var1 = 1; 4

深入理解C語言記憶體管理

之前在學Java的時候對於Java虛擬機器中的記憶體分佈有一定的瞭解,但是最近在看一些C,發現居然自己對於C語言的記憶體分配了解的太少。 問題不能拖,我這就來學習一下吧,爭取一次搞定。 在任何程式設計環境及語言中,記憶體管理都十分重要。 記憶體管理的基本概念 分析C語言記憶體的分佈先從Linux下可執行

C語言記憶體管理超詳解

補充: 1.一個正在執行著的C編譯程式佔用的記憶體分為棧區、堆區、未初始化資料區(BBS)、初始化資料區、程式碼區5個部分。 (1)棧區:存放函式的引數值、區域性變數的值。由編譯器自動分配釋放。 (2)堆區:用於動態記憶體分配。由使用者通過malloc或new函式分配,由使

c語言記憶體管理、野指標、malloc

C語言一共定義四個區塊:程式碼區、全域性變數和靜態變數區、棧、堆 針對四個區塊,使用者的記憶體分配也有三種不同的方式: 靜態變數區:在程式碼編譯的時候就分配好了,比如全域性變數,被static

C語言記憶體管理(初級)----連結串列

    上一篇文章裡實現了二維動態陣列的建立和銷燬,現在來看一個稍加複雜一點的例項:連結串列,讀者需具有連結串列的基本知識,本文的連結串列實現與讀者所熟知的實現有一些差異。     假定我們要寫一個計算器程式,它接受一個字串形式的表示式,然後計算並輸出其結果,我們先要解決的

C語言記憶體管理機制的一點小問題

先來一張高能的圖: 這張圖片上的結果是一個細心地小夥兒發現的。。嗯不如說是個瘋狂的小夥兒。 第一行裡指標a,b竟然有相同的值,看這結果是不是很像引用? 理論上來說要用指標是要給它分配記憶體空間的

利用C語言記憶體管理模擬實驗

模擬實現一個簡單的固定(可變)分割槽儲存管理系統 實驗內容 (1)建立相關的資料結構,作業控制塊、已分配分割槽及未分配分割槽 (2)實現一個分割槽分配演算法,如最先適應演算法、最優或最壞適應分配演算法 (3)實現一個分割槽回收演算法 (4)給定一個作業

C語言記憶體的動態儲存管理2-空閒連結串列

空閒連結串列三種結構形式: (1)所有請求的記憶體大小相同。這是一種最簡單的動態儲存管理方式。 對此,系統通常的做法是: a)系統啟動時,將記憶體按大小均分成若干個塊,並形成一個連結串列。 b)分配時,只需將連結串列中第一個節點分配給使用者即可,無需掃描整個連結串列。 c)回

c/c++】記憶體管理

文章目錄 1.c/c++記憶體分配 2.C語言中動態記憶體管理方式malloc/calloc/realloc與free 3.C++記憶體管理方式 3.1new/delete操作內建型別 3.2new和delete操

8、【C++】記憶體管理

C++記憶體管理 一、記憶體分配方式     在C++中記憶體被分為5個區,分別是:棧區、堆區、自由儲存區、全域性/靜態儲存區和常量儲存區。 1、棧區     在執行函式時,函式內區域性變數的儲存單元都可一在棧上建立,函式執行結束時,這些儲存單元自動被釋放。棧記憶體分配運算內建與

c語言--記憶體學習總結

變數在記憶體中的形式 1.定義 作用域 :變數聲明後時,只有在一定區域內才能被訪問 儲存期:程式中變數的儲存終止時間 連結: 連結屬性是為了說明在不同檔案中出現的相同識別符號應該如何處理 作用域(分類) 塊作用域 函式作用域

C語言記憶體分配規則

動態儲存區(堆) malloc動態分配在heap堆區。 程式設計師自己分配自己釋放。 動態儲存區(棧) 自動變數、const變數在stack棧區。 系統自動分配釋放。 靜態儲存區 extern全域性變數在static靜態儲存區。一旦分配,不會被回收,可讀可寫 程式程式

c語言記憶體的理解

      首先如圖記憶體分四區  棧區(stack)—由編譯器自動分配釋放,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。 堆區(heap)—一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時

C語言記憶體區域

記憶體 變數 變數型別 作用域 生命週期 儲存位置 區域性變數 函式內部 從變數建立到函式結束 棧區 全域性變數

C語言 記憶體分配和static關鍵字

C語言記憶體分配機制 (1)程式碼區(text segment)。.text程式碼區指令根據程式設計流程依次執行,對於順序指令,則只會執行一次(每個程序),如果反覆,則需要使用跳轉指令,如果進行遞迴,則需要藉助棧來實現。程式碼區的指令中包括操作碼和要操作的物件(

C語言—學生管理系統

2018.11.14 將連結串列作為記憶體資料模型,將檔案作為資料庫,將終端作為互動介面。 讀檔案生成連結串列,修改連結串列寫入檔案。 1.初始化現有資料。 2.讀檔案生成連結串列。 3.操作連結串列(增、查、改、刪、排序)。 4.寫連結串列到檔案。 (Linux下vim編輯器) 1

C語言--記憶體(說法二)

原始碼編譯之後,分為兩個狀態:儲存時、執行時。 儲存時  在linux環境下,可以對編譯好的二進位制檔案執行size指令可以獲取該二進位制可執行檔案的結構情況: # size test.out 程式碼區 全域性初始化資料區/靜態資料區

C語言--記憶體(說法一)

轉載自:https://www.cnblogs.com/yif1991/p/5049638.html  在計算機系統,特別是嵌入式系統中,記憶體資源是非常有限的。尤其對於移動端開發者來說,硬體資源的限制使得其在程式設計中首要考慮的問題就是如何有效地管理記憶體資源。本文是作者在學習C語言記