C/C++常見指針錯誤 and 內存訪問越界

1) 內存分配未成功,卻使用了它。

???編程新手常犯這種錯誤,因為他們沒有意識到內存分配會不成功。常用解決辦法是,在使用內存之前檢查指針是否為NULL。如果指針p是函數的參數,那么在函數的入口處用assert(p!=NULL)進行檢查。如果是用malloc或new來申請內存,應該用if(p==NULL) 或if(p!=NULL)進行防錯處理。


2) 內存分配雖然成功,但是尚未初始化就引用它。

???犯這種錯誤主要有兩個起因:一是沒有初始化的觀念;二是誤以為內存的缺省初值全為零,導致引用初值錯誤(例如數組)。內存的缺省初值究竟是什么并沒有統一的標準,盡管有些時候為零值,我們寧可信其無不可信其有。所以無論用何種方式創建數組,都別忘了賦初值,即便是賦零值也不可省略,不要嫌麻煩。


3) 內存分配成功并且已經初始化,但操作越過了內存的邊界。

???例如在使用數組時經常發生下標“多1”或者“少1”的操作。特別是在for循環語句中,循環次數很容易搞錯,導致數組操作越界。


4) 忘記了釋放內存,造成內存泄露。

???含有這種錯誤的函數每被調用一次就丟失一塊內存。剛開始時系統的內存充足,你看不到錯誤。終有一次程序突然死掉,系統出現提示:內存耗盡。動態內存的申請與釋放必須配對,程序中malloc與free的使用次數一定要相同,否則肯定有錯誤(new/delete同理)。


5) 釋放了內存卻繼續使用它。?

有三種情況: (1)程序中的對象調用關系過于復雜,實在難以搞清楚某個對象究竟是否已經釋放了內存,此時應該重新設計數據結構,從根本上解決對象管理的混亂局面。 (2)函數的return語句寫錯了,注意不要返回指向“棧內存”的“指針”或者“引用”,因為該內存在函數體結束時被自動銷毀。 (3)使用free或delete釋放了內存后,沒有將指針設置為NULL。導致產生“野指針”。 【規則7-2-1】用malloc或new申請內存之后,應該立即檢查指針值是否為NULL。防止使用指針值為NULL的內存。 【規則7-2-2】不要忘記為數組和動態內存賦初值。防止將未被初始化的內存作為右值使用。 【規則7-2-3】避免數組或指針的下標越界,特別要當心發生“多1”或者“少1”操作。 【規則7-2-4】動態內存的申請與釋放必須配對,防止內存泄漏。 【規則7-2-5】用free或delete釋放了內存之后,立即將指針設置為NULL,防止產生“野指針”。

參見http://hi.baidu.com/wangysh/blog/item/56275bc2114b6e36e5dd3bc1.html

自己編寫的一個不小的程序一直在運行退出時出錯,我對指針的使用很仔細但很長時間檢查不到錯誤,最后發現在一個地方沒有遵照規則【7-2-5】,大家如果指針出錯,一定要仔細的慢慢檢查,相信自己。


c++內存訪問越界

1. 原理分析

經常有些新C++程序員問:C++的類的成員個數是不是有限制,為什么我加一個變量后程序就死了?或者說:是不是成員變量的順序很重要,為什么我兩個成員變量順序換一換程序就不行了?凡此種種之怪現象,往往都是內存訪問越界所致。

何謂內存訪問越界,簡單的說,你向系統申請了一塊內存,在使用這塊內存的時候,超出了你申請的范圍。例如,你明明申請的是100字節的空間,但是你由于某種原因寫入了120字節,這就是內存訪問越界。內存訪問越界的后果是:你的寫入破壞了本不屬于你的空間。

下面是一個簡單的例子:
int a;
char b[16]="abcd";
int c;

a = 1;
c = 2;
printf("a=%d,c=%d\n", a,c);
memset(b, 0,32); //注意這里訪問越界了,你只有16字節空間,卻修改了32字節
printf("a=%d,c=%d\n", a,c);

你可以看出,在memset前后,兩個printf語句打印出來的值并不一樣,因為memset越界后修改了a或者c的值(由于不同編譯器對變量在空間中順序的安排可能有不同策略,因此我用兩個變量,希望能抓到越界信息。對于VC,debug模式下系統添加了很多填充字節,你可能需要增加越界的數量才能看到效果)


2. 為什么增加一個變量后程序就崩潰了?
增加一個變量后,內存中變量的布局也發生了變化。如果一個內存越界破壞了一個不含指針的結構,程序雖然邏輯不對,但是不至于崩潰。但是如果增加變量后,內存訪問越界破壞了一個指針,則會導致程序崩潰。

例如:(這個例子沒看明白,好像有點問題)

int a;
char b[128];
//bool c;
char* d=new char[128];
int e;

b[136] = '\0';
b[137] = '\0';
b[138] = '\0';
b[139] = '\0';
strcpy(d, "haha");
注意, b訪問越界了8個字節位置處的4個字節。如果沒有c,那么越界破壞了e變量,不會導致程序崩潰。但是加上c之后,破壞的變量可能就是d了,由于指針被破壞后,一旦訪問就是內存訪問違例,導致程序崩潰。

這也解釋了為什么交換順序會導致程序崩潰。如果上面情況沒有變量c,你交換e和d,結構也是類似的,程序也一樣要崩潰。

3. 為什么有些情況越界了程序也沒錯?
這主要是說這個話的人對什么是“錯”沒有正確的認識。程序不是只有崩潰了才是錯!你破壞了別的變量,那個變量總有被使用的時候,盡管那個變量不會導致諸如程序崩潰、報警之類的嚴重錯誤,但是其計算結果必然是錯誤的。你說“程序沒錯”,是因為你根本沒有發現錯誤而已。這種情況甚至比程序直接崩潰還要惡劣,因為程序一旦崩潰你肯定會去查,可以在導致真正嚴重的問題之前就把問題解決了。而如果計算錯誤隱藏到很晚,你的損失就可能很大了。(例如,一顆衛星上天了,你才發現一臺儀器由于軟件故障無法測量真正的數據,那得多少損失?)

4. 如何解決內存訪問越界問題?
老實說沒有好的方法。遇到這種問題,首先你得找到哪里有內存訪問越界,而一個比較麻煩得問題在于,出現錯誤得地方往往不是真正內存越界得地方。對于內存訪問越界,往往需要進行仔細得代碼走查、單步跟蹤并觀察變量以及在調試環境得幫助下對變量進行寫入跟蹤(如VC6就有一旦變量被修改就break得機制)。

更重要得是,程序員要養成良好的編程習慣,在修改每個數組時一定要對這個數組有多少空間有清醒的認識,否則一旦出錯,找到原因是很痛苦的事情。


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/458783.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/458783.shtml
英文地址,請注明出處:http://en.pswp.cn/news/458783.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C#將dll打包到程序中

直接進入主題 先來看一個栗子,假設現在有一個第三方dll namespace TestLibrary1 {public class Test{public void Point(){Console.WriteLine("aaabbbccc");}} } TestLibrary1.dll在項目中引用,然后調用其中的方法Test,將輸出aaabbbccc using System;namespace Conso…

Exchange 2016集成ADRMS系列-12:域內outlook 2010客戶端測試

接下來,我們來到域內安裝了office 2010的機器上進行測試。 首先我們在客戶端上強制刷新組策略,把我們剛才設置的策略刷新下來。 然后我們可以運行gpresult /h result.html來看看策略是不是已經下來了。 策略下來之后,我們打開客戶端上面的out…

如何用css和HTML結合畫熊,結合偽元素實現的純CSS3高級圖形繪制

自小編上次整理了一些基礎圖形的繪制方法之后,大家都紛紛表示對css3的繪圖技巧學習很有幫助。雖說萬變不離其宗,再復雜的圖形也可以用最簡單的三角形或者圓弧組合出來,但仍有不少朋友反映,學會基本圖形也不懂得怎樣組合&#xff0…

基于C++中常見內存錯誤的總結

在系統開發過程中出現的bug相對而言是比較好解決的,花費在這個上面的調試代價不是很大,但是在系統集成后的bug往往是難以定位的bug(最好方式是打樁,通過打樁可以初步鎖定出錯的位置,如:進入函數前打印日志&…

UWP開發細節記錄:判斷文件類型

StorageFile.ContentType 屬性,是 string 類型,用來表示文件內容的 MIME 類型。例如,音樂文件可能有 "audio/mpeg" MIME 類型。(MSDN) MIME 類型的定義可以下面的鏈接找到: MIME Types - http://blogs.msdn.com/b/jaime…

Creating Apps With Material Design —— Creating Lists and Cards

轉載請注明 http://blog.csdn.net/eclipsexys 翻譯自Developer Android。時間倉促,有翻譯問題請留言指出,謝謝創建Lisst和Cards在你的應用程序創建復雜的清單,并與材料設計風格卡。您能夠使用RecyclerView和CardView部件。 創建RecyclerView …

計算機考研自命題院校雙非,計算機考研408——951211院校匯總

眾所周知,計算機考研408計算機學科基礎綜合難度與一些頂尖985自命題相比也是不落下風的,號稱最難工科專業課(請忽略912這種殿堂級別的),難度大、知識點龐雜也是前些年眾多高校紛紛脫離408統考的原因。19年的計算機類考研火到爆炸,…

Could not get lock /var/lib/apt/lists/lock - open (11: Resource temporarily unavailable)

第一次鼓搗Docker,- - ! 報錯: serverubuntu1987:~$ sudo apt-get update E: Could not get lock /var/lib/apt/lists/lock - open (11: Resource temporarily unavailable) E: Unable to lock directory /var/lib/apt/lists/ 轉載于:https://www.cnblo…

新手學Struts(一)----JSP+Servlet講解MVC實現原理

MVC基本原理一個簡單的例子改良的例子Struts基本流程的實現最近在學SSH(Struts HibernateSpring),這也算是一個比較經典的框架了,之前都是看人家大牛說這個框架,那個框架,說的真溜,自己也是佩服的五體投地啊…

中國首臺千萬億次超級計算機,中國首臺千萬億次超級計算機首批設備開始試用...

新華社天津1月13日電(記者 周潤健 羅捷)記者13日從國家超級計算天津中心獲悉,中國首臺千萬億次超級計算機“天河一號”首批設備調試工作結束,具備向客戶提供服務的條件,“天河一號”…

Outlook Express 錯誤代碼表

錯誤碼 意義 一般 0x800C01310x800C013E 可能是 Folders.dbx 檔案屬性錯誤或損壞. 0x800CCC00 身份驗證(Authentication)未載入 0x800CCC01 認證(Certificate)內容錯誤 0x800CCC02 認證日期錯誤 0x800CCC03 使用者已聯機 0x800CCC…

USB設備枚舉過程

(1)集線器檢測新設備 (集線器的英文稱為“Hub”)主機集線器監視著每個端口的信號電壓,當有新設備接入時便可覺察。(集線器端口的兩根信號線的每一根都有15kΩ的下拉電阻,而每一個設備在D都有一個…

windows下apache+php+mysql 環境配置方法

轉自:http://www.jb51.net/article/30128.htm 一 準備 1 下載apache http://httpd.apache.org/download.cgi#apache24 httpd-2.2.22-win32-x86-openssl-0.9.8t.msiopenssl表示帶有openssl模塊,利用openssl可給Apache配置SSL安全鏈接 2 下載php http://wi…

計算機工作原理 公開課,《計算機的基本工作原理》公開課材料(11頁)-原創力文檔...

《計算機系統的組成》教學設計教師:吳軍一、學習者分析初一的學生,具有活潑好動的特點,懷著對初中生活的憧憬來到一個新的環境里,對每樣事物都充滿著好奇,都想去探個究竟。隨著社會的進步, 計算機的使用范圍…

USB枚舉過程分析

1. 枚舉是什么? 枚舉就是從設備讀取一些信息,知道設備是什么樣的設備,如何進行通信,這樣主機就可以根據這些信息來加載合適的驅動程序。調試USB設備,很重要的一點就是USB的枚舉過程,只要枚舉成功了,那么就…

linux -- read(), write()

read()函數 2011-03-23 16:28:37| 分類&#xff1a; linux | 標簽&#xff1a; |字號大中小 訂閱 read函數從打開的設備或文件中讀取數據。 #include <unistd.h> ssize_t read(int fd, void *buf, size_t count); 返回值&#xff1a;成功返回讀取的字節數&…

jquery的$.extend、$.fn.extend、 jQuery.extend( target, object1, [objectN])作用及區別

jQuery為開發插件提拱了兩個方法&#xff0c;分別是&#xff1a; jQuery.fn.extend();jQuery.extend(); 雖然 javascript 沒有明確的類的概念&#xff0c;但是用類來理解它&#xff0c;會更方便。 jQuery便是一個封裝得非常好的類&#xff0c;比如我們用 語句 $("#btn1&…

CATia對計算機配置要求,【2人回答】求CATIA對電腦的詳細配置要求-3D溜溜網

回答&#xff1a;1、內存要求在32G和64G之間。2、硬盤要求選擇7200轉機械硬盤&#xff0c;4k以上分辨&#xff0c;就選擇SSD固態硬盤。3、CPU要求睿頻在4.1GHZ以上&#xff0c;核心在6和8核之間。4、顯卡要求顯存在6GB和11GB之間&#xff0c;位寬要求在192bit和384bit之間。5、…

如何制作自動更新程序?

原文出自&#xff1a;http://blog.csdn.net/metaphysis/article/details/18866631 如何制作自動更新程序&#xff1f; [版權所有 邱秋 2014 metaphysisyeah.net, 轉載請注明出處] 最近為單位寫了一個C/S結構的軟件&#xff0c;這個軟件是工作在單位的局域網內的。為了減輕為程序…

包含JS交互的混淆出錯

2019獨角獸企業重金招聘Python工程師標準>>> 小上司離職&#xff0c;我接手他負責的項目&#xff0c;進行版本更新的時候&#xff0c;在生成jar包測試的時候&#xff0c;點擊按鈕沒有反應&#xff0c;頁面是webview&#xff0c;按鈕則是與js交互&#xff0c;logcat打…