亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C迷途指針詳解

 更新時間:2014年09月10日 09:08:31   投稿:shichen2014  
這篇文章主要介紹了C迷途指針,迷途指針又稱為懸空指針、野指針,其對C程序的安全性與穩(wěn)定性影響巨大,本文對其原理與檢測方法做了較為詳盡的分析,需要的朋友可以參考下

本文較為詳盡的講述了C語言的迷途指針,分析了其概念、原理與檢測方法。分享給大家供大家參考。具體如下:

一般來說,在計算機編程領(lǐng)域中,迷途指針,或稱懸空指針、野指針,指的是不指向任何合法的對象的指針。

當所指向的對象被釋放或者收回,但是對該指針沒有作任何的修改,以至于該指針仍舊指向已經(jīng)回收的內(nèi)存地址,此情況下該指針便稱迷途指針。若操作系統(tǒng)將這部分已經(jīng)釋放的內(nèi)存重新分配給另外一個進程,而原來的程序重新引用現(xiàn)在的迷途指針,則將產(chǎn)生無法預(yù)料的后果。因為此時迷途指針所指向的內(nèi)存現(xiàn)在包含的已經(jīng)完全是不同的數(shù)據(jù)。通常來說,若原來的程序繼續(xù)往迷途指針所指向的內(nèi)存地址寫入數(shù)據(jù),這些和原來程序不相關(guān)的數(shù)據(jù)將被損壞,進而導(dǎo)致不可預(yù)料的程序錯誤。這種類型的程序錯誤,不容易找到問題的原因,通常會導(dǎo)致段錯誤(Linux系統(tǒng)中)和一般保護錯誤(Windows系統(tǒng)中)。如果操作系統(tǒng)的內(nèi)存分配器將已經(jīng)被覆蓋的數(shù)據(jù)區(qū)域再分配,就可能會影響系統(tǒng)的穩(wěn)定性。

某些編程語言允許未初始化的指針的存在,而這類指針即為野指針。野指針所導(dǎo)致的錯誤和迷途指針非常相似,但野指針的問題更容易被發(fā)現(xiàn)。

迷途指針的成因

在很多編程語言中(如C語言)從內(nèi)存中刪除一個對象或者返回時刪除棧幀后,并不會改變相關(guān)的指針的值。該指針仍然指向原來的內(nèi)存地址,即使引用已經(jīng)刪除,現(xiàn)在也可能已經(jīng)被其它進程使用了。

一個直接的例子,如下所示:

{
  char *cp = NULL;
  /* ... */
  {
    char c;
    cp = &c;
  } /* c falls out of scope */     
   /* cp is now a dangling pointer */
}

上述問題的解決方法是在該部分程序退出之前立即給CP賦0值(NULL)。另一個辦法是保證CP在沒有初始化之前,將不再被使用。

迷途指針經(jīng)常出現(xiàn)在混雜使用malloc() 和 free() 庫調(diào)用: 當指針指向的內(nèi)存釋放了,這時該指針就是迷途的。和前面的例子一樣,一個避免這個錯誤的方法是在釋放它的引用后將該指針的值重置為NULL,如下所示:

#include <stdlib.h>
{
  char *cp = malloc ( A_CONST );
  /* ... */
  free ( cp );   /* cp 現(xiàn)在變成了一個懸空指針 */
  cp = NULL;    /* cp 現(xiàn)在不是懸空了 */
  /* ... */
}

有個常見的錯誤是當返回一個基于棧分配的局部變量的地址時,一旦調(diào)用的函數(shù)返回,分配給這些變量的空間將被回收,此時它們擁有的是"垃圾值"。

int * func ( void )
{
  int num = 1234;
  /* ... */
  return &num;
}

在調(diào)用func之后一段時間,嘗試從該指針中讀取num的值,可能仍然能夠返回正確的值(1234),但是任何接下來的函數(shù)調(diào)用會覆蓋原來的棧為num分配的空間。這時,再從該指針讀取num的值就不正確了。如果要使一個指向num的指針都返回正確的num值,則需要將該變量聲明為static。

野指針的產(chǎn)生

野指針指的是還沒有初始化的指針。嚴格地說,編程語言中每個指針在初始化前都是野指針。

一般于未初始化時便使用指針就會產(chǎn)生問題。大多數(shù)的編譯器都能檢測到這一問題并警告用戶。

int f(int i)
{
  char* cp;  //cp 是野指針
  static char* scp; //scp 不是野指針,靜態(tài)變量自動初始化為0并保留它們的值
//使用這種特征可能被認為壞的編程風(fēng)格
}

迷途指針導(dǎo)致的安全漏洞

如同緩存溢出錯誤,迷途指針/野指針這類錯誤經(jīng)常會導(dǎo)致安全漏洞。 例如,如果一個指針用來調(diào)用一個虛函數(shù),由于vtable指針被覆蓋了,因此可能會訪問一個不同的地址(指向被利用的代碼)?;蛘撸绻撝羔樣脕韺懭雰?nèi)存,其它的數(shù)據(jù)結(jié)構(gòu)就有可能損壞了。一旦該指針成為迷途指針,即使這段內(nèi)存是只讀的,仍然會導(dǎo)致信息的泄露(如果感興趣的數(shù)據(jù)放在下一個數(shù)據(jù)結(jié)構(gòu)里面,恰好分配在這段內(nèi)存之中)或者訪問權(quán)限的增加(如果現(xiàn)在不可使用的內(nèi)存恰恰被用來安全檢測).

避免迷途指針的錯誤

避免迷途指針,有一種受歡迎的方法——即使用智能指針(Smart pointer)。智能指針使用引用計數(shù)來回收對象。一些其它的技術(shù)包括tombstone法和locks-and-keys法。

另外,可以使用 DieHard 內(nèi)存分配器,它虛擬消除了類似其它內(nèi)存錯誤(不合法或者兩次釋放內(nèi)存)的迷途指針錯誤。

還有一種辦法是貝姆垃圾收集器,一種保守的垃圾回收方法,能夠替代C和C++中標準內(nèi)存分配函數(shù)。這種方法完全消除了迷途指針的錯誤,通過去除內(nèi)存釋放的函數(shù)代之以垃圾回收器完成對象的回收。

像Java語言,迷途指針這樣的錯誤是不會發(fā)生的,因為Java中沒有明確地重新分配內(nèi)存的機制。而且垃圾回收器只會在對象的引用數(shù)為零時重新分配內(nèi)存。

迷途指針的檢測

為了能發(fā)現(xiàn)迷途指針,一種普遍的編程技術(shù)——一旦指針指向的內(nèi)存空間被釋放,就立即把該指針置為空指針或者為一個非法的地址。當空指針被重新引用時,此時程序?qū)⒓赐V?,這將避免數(shù)據(jù)損壞或者某些無法預(yù)料的后果。這將使接下來的編程過程產(chǎn)生的錯誤變得容易發(fā)現(xiàn)和解決了。這種技術(shù)在該指針有多個復(fù)制時就無法起到應(yīng)有的作用了。

一些調(diào)試器會自動地用特定的模式來覆蓋已經(jīng)釋放的數(shù)據(jù),如0xDEADBEEF (Microsoft's Visual C/C++ 調(diào)試器,例如,根據(jù)哪種類型被釋放采用 0xCC,0xCD 或者 0xDD)。這種方法通過將數(shù)據(jù)無用化,來防止已經(jīng)釋放的數(shù)據(jù)重新被使用。這種方法的作用是非常顯著的 (該模式可以幫助程序來區(qū)分哪些內(nèi)存是剛剛釋放的)。

某些工具,如Valgrind, Mudflap或者 LLVM可以用來檢測迷途指針的使用。

總的來說,迷途指針對C程序安全性影響巨大,是C程序員必須謹慎處理的一個問題。相信本文所述對大家C程序設(shè)計有一定的借鑒價值。

相關(guān)文章

  • c語言線程終止練習(xí)示例

    c語言線程終止練習(xí)示例

    這篇文章主要介紹了c語言線程終止練習(xí)示例,需要的朋友可以參考下
    2014-04-04
  • 詳細分析C++ 多態(tài)和虛函數(shù)

    詳細分析C++ 多態(tài)和虛函數(shù)

    這篇文章主要介紹了C++ 多態(tài)和虛函數(shù)的相關(guān)資料,文中示例代碼非常詳細,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • QT?UDP網(wǎng)絡(luò)編程實現(xiàn)簡單消息傳輸

    QT?UDP網(wǎng)絡(luò)編程實現(xiàn)簡單消息傳輸

    這篇文章主要為大家詳細介紹了QT?UDP網(wǎng)絡(luò)編程實現(xiàn)簡單消息傳輸,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C語言輸出唯一的子串

    C語言輸出唯一的子串

    這篇文章主要介紹了C語言輸出唯一的子串,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-12-12
  • 完全掌握C++編程中構(gòu)造函數(shù)使用的超級學(xué)習(xí)教程

    完全掌握C++編程中構(gòu)造函數(shù)使用的超級學(xué)習(xí)教程

    這篇文章主要介紹了C++中的構(gòu)造函數(shù),包括C++11標準中的新特性的介紹,十分推薦!需要的朋友可以參考下
    2016-01-01
  • vscode調(diào)試gstreamer源碼的詳細流程

    vscode調(diào)試gstreamer源碼的詳細流程

    在本文中主要介紹了如何使用vscode調(diào)試C++和python程序,并進一步分析了如何調(diào)試gstreamer源碼,講述了如何調(diào)試gstreamer源碼的具體流程,感興趣的朋友跟隨小編一起看看吧
    2023-01-01
  • C語言用函數(shù)指針實現(xiàn)一個特別的計算器

    C語言用函數(shù)指針實現(xiàn)一個特別的計算器

    函數(shù)指針是一個指針變量,它可以存儲函數(shù)的地址,然后使用函數(shù)指針,下面這篇文章主要給大家介紹了關(guān)于C語言用函數(shù)指針實現(xiàn)計算器的方法,需要的朋友可以參考下
    2022-07-07
  • C++的cout.tellp()和cout.seekp()語法介紹

    C++的cout.tellp()和cout.seekp()語法介紹

    無論是使用 cout 輸出普通數(shù)據(jù),用 cout.put() 輸出指定字符,還是用 cout.write() 輸出指定字符串,數(shù)據(jù)都會先放到輸出流緩沖區(qū),待緩沖區(qū)刷新,數(shù)據(jù)才會輸出到指定位置,本文給大家介紹一下C++的cout.tellp()和cout.seekp()語法,需要的朋友可以參考下
    2023-09-09
  • C語言函數(shù)棧幀解析

    C語言函數(shù)棧幀解析

    下面小編就為大家?guī)硪黄獪\談C語言函數(shù)調(diào)用參數(shù)壓棧的相關(guān)問題。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-09-09
  • 深入了解c++數(shù)組與指針

    深入了解c++數(shù)組與指針

    這篇文章主要介紹了c++數(shù)組與指針的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)c++,感興趣的朋友可以了解下
    2020-08-08

最新評論