1. 程式人生 > >C/C++ 使用delete刪除指標需小心 “野指標”

C/C++ 使用delete刪除指標需小心 “野指標”

本文轉載自:

眾所周知,最開始我們用new來建立一個指標,那麼等我們用完它之後,一定要用delete將該指標刪掉。但是,值得注意的是,難道就僅僅是刪除這個指標這麼簡單的麼?下面,我們用一個程式來說明這個問題:

#include
02 using namespace std;
03 int main()
04 {
05 int *p=new int;
06
    *p=3;
07     cout<<"將3賦給p的地址後,指標p讀取的值:"<<*p<<endl;
08 delete p;
09     cout<<"刪除空間後,指標p讀取的值:"<<*p<<endl;
10 long *p1=new long;
11     *p1=100;
12
    cout<<"建立新空間後,指標p中儲存的地址:"<<p<<endl;
13     cout<<"指向新空間的指標p1儲存的地址:"<<p1<<endl;
14     *p=23;
15     cout<<"將23賦給p的地址後,指標p讀取的值:"<<*p<<endl;
16     cout<<
"將23賦給p的地址後,指標p1讀取的值:"<<*p1<<endl;
17 delete p1;
18 return 0;
19 }

       在上面這個程式中,我們在第8行就將指標p利用delete刪掉了。但是,我們來看看程式的輸出結果:

      對照著上面的程式,我們來分析一下這個輸出。首先,我們在程式的第5行初始化了一個指標p。之後輸出指標p讀取的值。由於第6行的原因,程式肯定會輸出3 了。之後,我們在程式的第8行刪除了這個指標p。但是我們驚奇的發現,在程式的第9行竟然可以輸出指標p讀取的值。我們不是已經把它刪了麼?其實不 然,debug,上圖:

從監視視窗中,我們可以看見雖然程式的第8行已經將指標p刪除了,但是在監視視窗中p仍然存在,只是*p所指向的值不再是原來的3了,而是一個隨機數。這裡就說明了一個非常重要的概念:我們在刪除一個指標之後,編譯器只會釋放該指標所指向的記憶體空間,而不會刪除這個指標本身。

      然後我們接著往下分析。在程式的第10行我們又建立了一個long型的指標p1。在12行與13行的輸出中我們驚奇地發現,指標p儲存的地址居然和指標 p1儲存的地址一模一樣!這個就說明了指標p和指標p1都指向記憶體的同一個地方!!!出現這種狀況的原因其實是由於編譯器。編譯器預設將釋放掉的記憶體空間回收然後分配給新開闢的空間。所 以在第11行由於我們新開闢了一個可以儲存long型變數的空間並且由p1來指向它,那麼這裡的p1指向的其實就是在程式第8行釋放掉的記憶體空間,即p指 向的記憶體空間!所以,這就導致了兩個指標同時指向同一個記憶體空間。這是多不安全的一件事情啊!要知道,我們是把指標p刪了的啊!如果再重新對*p進行賦值 操作,那麼不是會連著*p1一起改動麼?

      果然,讓我們擔心的事情出現了。我們明明在程式的第11行中定義了*p1的值為100,但是在輸出上面,指標p1讀取的值竟然也是23。這個原因就是因為 野指標p造成的。我們可以看到,在程式的第14行我們將23賦給了*p。又由於p和p1指向的是同一塊記憶體單元,所以在這裡相當於也將p1所指向的記憶體單 元中的值(原來是100),改成了23!這樣必然會導致程式的出錯!

       那麼我們就不禁要問了,對於這種由於野指標造成的問題,有沒有解決的方法呢?答案當然是有的了。我們只需要牢記下面這句話:

在刪除一個指標之後,一定將該指標設定成空指標(即在delete *p之後一定要加上: p=NULL)

      我們來看一下在stdio.h中關於關鍵字NULL的定義:

相關推薦

C/C++ 使用delete刪除指標小心指標

本文轉載自: 眾所周知,最開始我們用new來建立一個指標,那麼等我們用完它之後,一定要用delete將該指標刪掉。但是,值得注意的是,難道就僅僅是刪除這個指標這麼簡單的麼?下面,我們用一個程式來說明這個問題: #include

從預設解構函式學習c++,new,delete,記憶體洩漏,指標

預設解構函式:當系統沒有顯式定義解構函式,編譯器同樣會為物件定義一個預設解構函式,預設的解構函式只能釋放普通資料成員所佔用的空間,無法通過釋放通過new和malloc進行申請的空間,因此避免記憶體洩漏,我們要顯式的解構函式對申請的空間釋放。 記憶體洩漏(Memory Leak)是指程式中己動態分配的堆記憶體

C語言指標產生的原因及解決方法

C語言野指標產生的原因及解決方法 情況一 原因 指標變數宣告時沒有被初始化。 解決辦法 指標宣告時初始化,可以是具體的地址值,也可讓它指向NULL。 情況二 原因 指標 p 被 free 或者 delete 之後,沒有置為 NULL。 解決辦法 指標指向的記憶體空間被

C語言中指標

野指標 野指標通常是因為指標變數中儲存的值不是一個合法的記憶體地址而造成的 野指標不是NULL指標,是指向不可用記憶體的指標 NULL指標不容易用錯,因為if語句很好判斷一個指標是不是NULL (注意

C/C++ 指標 殭屍物件

今天在實現平衡二叉樹的一系列操作的時候,發現了一個以前不經常注意的地方,記錄一下; 每個程式在執行時都會佔用一塊可用的記憶體空間(malloc、new),用於存放動態分配的物件,此記憶體空間稱為自由儲存區或堆。 在使用完這塊記憶體之後,就需要我們自己釋放這塊記憶體,否

C/C++基礎----特殊工具和技術 (過載new和delete,RTT,限定作用域的列舉型別,類成員指標,巢狀類,區域性類,volatile,連結指示 extern “C”)

過載new和delete 1呼叫operator new( 或new[])標準庫函式分配足夠大的、原始的、未命名的記憶體空間以便儲存特定型別的物件 2編譯器執行相應地建構函式以構造這些物件,併為其傳入初始值 3返回一個指向該物件的指標 可以在全域性作用域定義operator new,也可以定義為成員函式

c語言==指標形成原理、造成的危害及避免方法(22)

野指標 : 隨機指向一塊記憶體的指標成為野指標。(因為在計算機中,記憶體的分配由作業系統來管理,要使用記憶體需要先向作業系統申請,系統分配後才可以使用,而野指標的記憶體空間是隨機分配的,屬於非法訪問記憶體。) 野指標造成的錯誤叫做記憶體洩漏,但存在

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

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

(整合多篇文章)C++懸垂指標指標、記憶體洩漏和垃圾回收機制

C++的記憶體回收機制 當我們使用new為一個物件分配了空間之後,在這個物件結束使用之後,我們必須人為的去釋放這塊記憶體(delete) Java的記憶體回收機制  當用new 建立一個Java物件時,它可以存活於作用域之外。所以在上述程式碼中,引用 str(

C語言 空指標指標

int *p1 = NULL;//空指標 int *p2;//野指標指向空的指標是空指標,指向一塊未知區域的指標是野指標例如  int *p = 0x123456;   這就是一個野指標,我們並不知道這

徹底搞清c/c++中的幾個指標概念:懸垂指標和智慧指標以及啞指標指標

先看看下面兩段程式碼執行結果: #include<iostream> //#include <windows.h> using namespace std; int *p=NULL; void fun() {int i=10;p=&i;} v

語言--c--空指標(NULL,0),指標,void*的講解

空指標(NULL,0),野指標,void*的講解  (2011-09-05 12:41:48) 轉載 一:野指標 “野指標”不是NULL指標,是指向“垃圾”記憶體的指標。 “野指標”的成因主要有兩種: (1)指標變數沒有被初始化。任何指標變數剛被建立時不會

iOS開發時OC與C的混編中,strcpy導致的記憶體溢位、指標

在最近的專案開發中,由於需要使用C語言的演算法供給OC專案呼叫,所以研究了一下OC與C的混編及.a庫的相關生成。而在混編的過程中,C語言的演算法都能正常呼叫了,但是被一個問題困擾了很長一段時間,就是在

C 語言】記憶體管理 ( 動態記憶體分配 | 棧 | 堆 | 靜態儲存區 | 記憶體佈局 | 指標 )

一. 動態記憶體分配 1. 動態記憶體分配相關概念 動態記憶體分配 : 1.C語言操作與記憶體關係密切 : C 語言中的所有操作都與記憶體相關 ; 2.記憶體別名 : 變數 ( 指標變數 | 普通變數 ) 和 陣

C/C++指標之--NULL指標,零指標指標

經常在聽到野指標的時候一臉懵逼,現在是得好好總結一下了。感謝fly1988happy前輩,他的blog裡面還寫了一些關於空指標的保護政策,這些point等我對虛擬空間的訪問許可權進行總結時,再來探討。 1.空指標常量 0、0L、’\0’、3 - 3、0 *

【linux c】什麼是指標以及如何避免指標_學習筆記_010

1.首先以一個示例來認識野指標: #include <stdio.h> int main() { int * p; scanf("%d", p); print

C++進階】C++中的空指標指標

歸根結底,程式中所使用的資料都需要從物理裝置上獲取,即程式中的資料需要從一個真實的實體地址中讀取或者寫入。所以當一個指標的邏輯地址可以通過計算能夠準確無誤的對映到一個正確的實體地址上時,這時候資料的訪問就是正確的,程式的執行也沒有任何問題。如果一個指標為空指標,那麼該指標所指向的邏輯地址空間位於空指標賦值分割

C語言指標的產生原因及避免辦法

見如下程式例項:#include <stdio.h> #include <stdlib.h> int main() { char *p1 = NULL; printf("

C程式中可怕的指標

一、疑問點指標是C語言一個很強大的功能,同時也是很容易讓人犯錯的一個功能,用錯了指標,輕者只是報個錯,重者可能整個系統都崩潰了。下面是大家在編寫C程式時,經常遇到的一種錯誤的使用方法,也許在你的學習和工作中就是這樣用的,很危險。例項程式如圖1所示: 圖1 例項程式這段程式比較簡單,str1指向的記憶體區域

【Objective-C】09-空指針和指針

復制 註意 一個 20px 行程 def mage tle 指向 一、什麽是空指針和野指針 1.空指針 1> 沒有存儲不論什麽內存地址的指針就稱為空指針(NULL指針) 2> 空指針就是被賦值為0的指針。在沒有