C++ 11 nullptr 空指針示例詳解
C++11 中,nullptr 是空指針,可用來給 (指向任意對(duì)象類型的) 指針賦值。
【 0. 問題背景 】
0.1 野指針和懸空指針
總結(jié)
野指針 | 懸空指針 | |
---|---|---|
產(chǎn)生原因 | 指針變量未被初始化 就開始使用。 | 對(duì)象被刪除或內(nèi)存塊被釋放后,指向該內(nèi)存的指針沒有被及時(shí)設(shè)為nullptr,指針指向一塊無效內(nèi)存。 |
危害 | 使用野指針可能會(huì)導(dǎo)致 程序崩潰,因?yàn)樗赡軙?huì)隨機(jī)訪問未知內(nèi)存。 | 如果繼續(xù)使用它,可能會(huì)操作一些已被操作系統(tǒng)回收或重新分配給其他程序的內(nèi)存,從而導(dǎo)致 數(shù)據(jù)損壞或程序異常。 |
避免方法 | 在 定義指針的同時(shí)完成初始化操作 ,即便該指針的指向尚未明確,也要將其初始化為空指針。 | 應(yīng)該在釋放內(nèi)存或?qū)ο箐N毀后將指針設(shè)置為空指針 。 |
野指針和懸空指針的示例
#include <iostream> using namespace std; int main() { // 野指針示例 int* wildPtr; // 未初始化的指針 // 未定義行為:嘗試使用未初始化的指針 //cout << *wildPtr << endl; // 可能導(dǎo)致崩潰 // 懸空指針示例 int* danglingPtr = new int(10); // 分配內(nèi)存 delete danglingPtr; // 釋放內(nèi)存 // 未定義行為:嘗試訪問已釋放的內(nèi)存 //cout << *danglingPtr <<endl; // 可能導(dǎo)致崩潰 return 0; }
0.2 傳統(tǒng)空指針 NULL
傳統(tǒng)空指針 的基本語法
C++98/03 標(biāo)準(zhǔn)中,將一個(gè)指針初始化為空指針的方式有 2 種:
- 第一種,可以將指針明確指向 0(0x0000 0000)這個(gè)內(nèi)存空間。大多數(shù)操作系統(tǒng)都不允許用戶對(duì)地址為 0 的內(nèi)存空間執(zhí)行寫操作,若用戶在程序中嘗試修改其內(nèi)容,則程序運(yùn)行會(huì)直接報(bào)錯(cuò)。
- 第二種,可以將指針初始化為 NULL。NULL 并不是 C++ 的關(guān)鍵字,它是 C++ 為我們事先定義好的一個(gè)宏,并且它的值往往就是字面量 0(
#define NULL 0
)。
int *p = 0; int *p = NULL; //推薦使用
0.3 傳統(tǒng)空指針的局限性
C++ 中將 NULL 定義為字面常量 0,雖然能滿足大部分場(chǎng)景的需要,但個(gè)別情況下,它會(huì)導(dǎo)致程序的運(yùn)行和我們的預(yù)期不符,如下代碼所示:
- 對(duì)于 isnull(0) 來說,顯然它真正調(diào)用的是參數(shù)為整形的 isnull() 函數(shù);而對(duì)于 isnull(NULL),我們期望它實(shí)際調(diào)用的是參數(shù)為 void*c 的 isnull() 函數(shù),但觀察程序的執(zhí)行結(jié)果不難看出,并不符合我們的預(yù)期。
#include <iostream> using namespace std; void isnull(void* c) { cout << "void*c" << endl; } void isnull(int n) { cout << "int n" << endl; } int main(){ isnull(0); isnull(NULL); return 0; }
C++ 98/03 標(biāo)準(zhǔn)中,如果我們想令 isnull(NULL) 實(shí)際調(diào)用的是 isnull(void* c),就需要對(duì) NULL(或者 0)進(jìn)行強(qiáng)制類型轉(zhuǎn)換:如此,才會(huì)成功調(diào)用我們預(yù)期的函數(shù)。
isnull( (void*)NULL ); // 或者 isnull( (void*)0 );
【 1. 基本用法 】
- 由于 C++ 98 標(biāo)準(zhǔn)使用期間,NULL 已經(jīng)得到了廣泛的應(yīng)用,出于兼容性的考慮,C++11 標(biāo)準(zhǔn)并沒有對(duì) NULL 的宏定義做任何修改,即 傳統(tǒng)空指針NULL仍可用但是有BUG 。為了修正 C++ 存在的這一 BUG,C++ 標(biāo)準(zhǔn)委員會(huì)最終決定另其爐灶,在 C++11 標(biāo)準(zhǔn)中引入一個(gè)新關(guān)鍵字,即 nullptr。
- nullptr_t 指針空值類型 是 C++11 新增加的數(shù)據(jù)類型。nullptr 是 nullptr_t 類型的右值常量,專用于初始化空類型指針,也就是說,nullptr 僅是該類型的一個(gè)已定義好可直接使用的實(shí)例對(duì)象 ,如果需要我們完全定義出多個(gè)同 nullptr 完全一樣的實(shí)例對(duì)象。
【 2. nullptr 的應(yīng)用 】
2.1 nullptr 解決 NULL 的遺留BUG
由于 nullptr 無法隱式轉(zhuǎn)換為整形,而可以隱式匹配指針類型 ,因此執(zhí)行結(jié)果和我們的預(yù)期相符。
總之在 C++11 標(biāo)準(zhǔn)下,相比 NULL 和 0,使用 nullptr 初始化空指針可以令我們編寫的程序更加健壯。
#include <iostream> using namespace std; void isnull(void *c){ cout << "void*c" << endl; } void isnull(int n){ cout << "int n" << endl; } int main() { isnull(NULL); isnull(nullptr); return 0; }
2.2 簡(jiǎn)單實(shí)例
不同類型的指針變量都可以使用 nullptr 來初始化,編譯器分別將 nullptr 隱式轉(zhuǎn)換成 int*、char* 以及 double* 指針類型。
int * a1 = nullptr; char * a2 = nullptr; double * a3 = nullptr;
到此這篇關(guān)于C++ 11 nullptr 空指針的文章就介紹到這了,更多相關(guān)C++ 11 nullptr 空指針內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言 strftime 格式化顯示日期時(shí)間的實(shí)現(xiàn)
下面小編就為大家?guī)硪黄狢語言 strftime 格式化顯示日期時(shí)間的實(shí)現(xiàn)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-12-12C++實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)的順序表詳解
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)動(dòng)態(tài)順序表,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11c++實(shí)現(xiàn)獲取當(dāng)前時(shí)間(精確至秒,毫秒和微妙)
這篇文章主要為大家詳細(xì)介紹了c++實(shí)現(xiàn)獲取當(dāng)前時(shí)間(可以精確至秒,毫秒和微妙)的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以參考一下2023-11-11c++ STL set_difference set_intersection set_union 操作
這篇文章主要介紹了c++ STL set_difference set_intersection set_union 操作,需要的朋友可以參考下2017-03-03C語言設(shè)計(jì)前中后隊(duì)列實(shí)例代碼
隊(duì)列最主要的作用就是用來管理數(shù)據(jù)流的,防止數(shù)據(jù)因?yàn)閭鬏旑l率過快得不到及時(shí)處理而丟失,下面這篇文章主要給大家介紹了關(guān)于C語言設(shè)計(jì)前中后隊(duì)列的相關(guān)資料,需要的朋友可以參考下2021-12-12