C/C++記憶體管理詳解

来源:http://www.cnblogs.com/zjd2626/archive/2017/05/30/6920662.html
-Advertisement-
Play Games

記憶體分配方式 簡介 在C++中,記憶體分成5個區,他們分別是堆、棧、自由存儲區、全局/靜態存儲區和常量存儲區。 棧:在執行函數時,函數內局部變數的存儲單元都可以在棧上創建,函數執行結束時這些存儲單元自動被釋放。棧記憶體分配運算內置於處理器的指令集中,效率很高,但是分配的記憶體容量有限。 堆:就是那些由 n ...


記憶體分配方式

簡介

  在C++中,記憶體分成5個區,他們分別是堆、棧、自由存儲區、全局/靜態存儲區和常量存儲區。
  :在執行函數時,函數內局部變數的存儲單元都可以在棧上創建,函數執行結束時這些存儲單元自動被釋放。棧記憶體分配運算內置於處理器的指令集中,效率很高,但是分配的記憶體容量有限。
  :就是那些由 new分配的記憶體塊,他們的釋放編譯器不去管,由我們的應用程式去控制,一般一個new就要對應一個 delete。如果程式員沒有釋放掉,那麼在程式結束後,操作系統會自動回收。
  自由存儲區:就是那些由malloc等分配的記憶體塊,他和堆是十分相似的,不過它是用free來結束自己的生命的。
  全局/靜態存儲區:全局變數和靜態變數被分配到同一塊記憶體中,在以前的C語言中,全局變數又分為初始化的和未初始化的,在C++裡面沒有這個區分了,他們共同占用同一塊記憶體區。
  常量存儲區:這是一塊比較特殊的存儲區,他們裡面存放的是常量,不允許修改。

 

常見的記憶體錯誤及其對策

  發生記憶體錯誤是件非常麻煩的事情。編譯器不能自動發現這些錯誤,通常是在程式運行時才能捕捉到。而這些錯誤大多沒有明顯的癥狀,時隱時現,增加了改錯的難度。有時用戶怒氣衝衝地把你找來,程式卻沒有發生任何問題,你一走,錯誤又發作了。 常見的記憶體錯誤及其對策如下:

  • 記憶體分配未成功,卻使用了它。編程新手常犯這種錯誤,因為他們沒有意識到記憶體分配會不成功。常用解決辦法是,在使用記憶體之前檢查指針是否為NULL。如果指針p是函數的參數,那麼在函數的入口處用assert(p!=NULL)進行檢查。如果是用mallocnew來申請記憶體,應該用if(p==NULL) 或if(p!=NULL)進行防錯處理。
  • 記憶體分配雖然成功,但是尚未初始化就引用它。犯這種錯誤主要有兩個起因:一是沒有初始化的觀念;二是誤以為記憶體的預設初值全為零,導致引用初值錯誤(例如數組)。記憶體的預設初值究竟是什麼並沒有統一的標準,儘管有些時候為零值,我們寧可信其無不可信其有。所以無論用何種方式創建數組,都別忘了賦初值,即便是賦零值也不可省略,不要嫌麻煩。
  • 記憶體分配成功並且已經初始化,但操作越過了記憶體的邊界。例如在使用數組時經常發生下標“多1”或者“少1”的操作。特別是在for迴圈語句中,迴圈次數很容易搞錯,導致數組操作越界。
  • 忘記了釋放記憶體,造成記憶體泄露。含有這種錯誤的函數每被調用一次就丟失一塊記憶體。剛開始時系統的記憶體充足,你看不到錯誤。終有一次程式突然死掉,系統出現提示:記憶體耗盡。動態記憶體的申請與釋放必須配對,程式中mallocfree的使用次數一定要相同,否則肯定有錯誤(new/delete同理)。
  • 釋放了記憶體卻繼續使用它。

  有三種情況:
  (1). 程式中的對象調用關係過於複雜,實在難以搞清楚某個對象究竟是否已經釋放了記憶體,此時應該重新設計數據結構,從根本上解決對象管理的混亂局面。
  (2). 函數的return語句寫錯了,註意不要返回指向“棧記憶體”的“指針”或者“引用”,因為該記憶體在函數體結束時被自動銷毀。
  (3). 使用freedelete釋放了記憶體後,沒有將指針設置為NULL導致產生“野指針”
  那麼如何避免產生野指針呢?這裡列出了5條規則,平常寫程式時多註意一下,養成良好的習慣。

規則1:用mallocnew申請記憶體之後,應該立即檢查指針值是否為NULL。防止使用指針值為NULL的記憶體。
規則2:不要忘記為數組和動態記憶體賦初值。防止將未被初始化的記憶體作為右值使用。
規則3:避免數組或指針的下標越界,特別要當心發生“多1”或者“少1”操作。
規則4:動態記憶體的申請與釋放必須配對,防止記憶體泄漏。
規則5:用freedelete釋放了記憶體之後,立即將指針設置為NULL,防止產生“野指針”。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 7.1 raw_input(): raw_input()是python 的內建函數,通過讀取控制台的輸入與用戶實現交互。 raw_input()可以讓用戶輸入字元串(即等待用戶輸入內容),並存放到一個變數里。 運行結果: 7.2 getpass模塊: 輸入密碼時,如果想要不可見,需要利用 getpa ...
  • 對坦克大戰情有獨鍾是因為大學時候第一次參加程式設計比賽就做的這個游戲。當時用的語言是Java,那個比賽讓我悟出了面向對象的強大之處,我也是從那時開始接觸設計模式的。對我而言,坦克大戰有著非同尋常的意義,所以一定要帶大家用C++實現一下。 坦克大戰 我們依然使用EasyX在控制台程式中製作這個游戲程式 ...
  • 本篇文章整理了幾道Linux下C語言的經典面試題,相信對大家更好的理解Linux下的C語言會有很大的幫助,歡迎大家探討指正。 1、如果在Linux下使用GCC編譯器執行下列程式,輸出結果是什麼? 答案如下: 2、C語言程式不使用任何條件運算符,列印出十次"Hello"? 答案如下: 或是: 3、如果 ...
  • 一、實驗原理 二、實驗步驟 三、實驗過程 1.(程式) (1)二分法:求 在區間(1,2)之間的根,取 (a)bipart.m: (b)fun1.m: (2)不動點迭代法:求方程在附近的根,取 (a)budong.m: (b)fun.m (3)牛頓迭代法:求方程在附近的根,取 newton.m: 2 ...
  • CloseHandle函數 來源:https://msdn.microsoft.com/en us/library/windows/desktop/ms724211(v=vs.85).aspx 作用 關閉一個打開的對象句柄。 語法 參數 hObject 已經打開的有效對象句柄。 返回值 如果函數操作 ...
  • 數據類型之集合 set set集合,是一個無序且不重覆的元素集合 A = set([1, 2, 3, 4, 5, 6,]) B = set([2, 3, 4, 5, 6, 7, 8]) type(A) type(B) class set(object): """ set() new empty se ...
  • 前言 前面已經學習了Apache Commons Beanutils包里的PropertyUtils和動態bean,接下來將學習剩下的幾個工具類,個人覺得還是非常實用的,特別是CollectionUtils; BeanUtils 簡單介紹下兩個方法的使用,populate和copyPropertie ...
  • 首先需要弄清楚npm與cnpm的區別(要看解決問題方案的情直接跳到最後): npm:npm(node package manager)是nodejs的包管理器,用於node插件管理(包括安裝、卸載、管理依賴等) cnpm:因為npm安裝插件是從國外伺服器下載,受網路影響大,可能出現異常,如果npm的 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...