C++ 11 nullptr 空指针示例详解

 更新时间:2024年10月09日 10:43:49   作者:MR_Promethus  
C++11标准引入了nullptr来替代传统的NULL,解决了NULL可能导致的类型混淆问题,nullptr是nullptr_t类型的实例,专用于初始化空类型指针,与整型不会发生隐式转换,从而使代码更健壮,它可以被隐式转换为任意类型的指针,提高了代码的安全性和可读性

C++11 中,nullptr 是空指针,可用来给 (指向任意对象类型的) 指针赋值。

【 0. 问题背景 】

0.1 野指针和悬空指针

总结

野指针悬空指针
产生原因指针变量未被初始化 就开始使用。对象被删除或内存块被释放后,指向该内存的指针没有被及时设为nullptr,指针指向一块无效内存。
危害使用野指针可能会导致 程序崩溃,因为它可能会随机访问未知内存。如果继续使用它,可能会操作一些已被操作系统回收或重新分配给其他程序的内存,从而导致 数据损坏或程序异常
避免方法定义指针的同时完成初始化操作 ,即便该指针的指向尚未明确,也要将其初始化为空指针。应该在释放内存或对象销毁后将指针设置为空指针

野指针和悬空指针的示例

#include <iostream>
using namespace std;
int main() {
    // 野指针示例
    int* wildPtr;  // 未初始化的指针
    // 未定义行为:尝试使用未初始化的指针
    //cout << *wildPtr << endl;  // 可能导致崩溃
    // 悬空指针示例
    int* danglingPtr = new int(10);  // 分配内存
    delete danglingPtr;              // 释放内存
    // 未定义行为:尝试访问已释放的内存
    //cout << *danglingPtr <<endl;  // 可能导致崩溃
    return 0;
}

0.2 传统空指针 NULL

传统空指针 的基本语法

C++98/03 标准中,将一个指针初始化为空指针的方式有 2 种:

  • 第一种,可以将指针明确指向 0(0x0000 0000)这个内存空间。大多数操作系统都不允许用户对地址为 0 的内存空间执行写操作,若用户在程序中尝试修改其内容,则程序运行会直接报错。
  • 第二种,可以将指针初始化为 NULL。NULL 并不是 C++ 的关键字,它是 C++ 为我们事先定义好的一个宏,并且它的值往往就是字面量 0(#define NULL 0)。
int *p = 0;
int *p = NULL; //推荐使用

0.3 传统空指针的局限性

C++ 中将 NULL 定义为字面常量 0,虽然能满足大部分场景的需要,但个别情况下,它会导致程序的运行和我们的预期不符,如下代码所示:

  • 对于 isnull(0) 来说,显然它真正调用的是参数为整形的 isnull() 函数;而对于 isnull(NULL),我们期望它实际调用的是参数为 void*c 的 isnull() 函数,但观察程序的执行结果不难看出,并不符合我们的预期。
#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 标准中,如果我们想令 isnull(NULL) 实际调用的是 isnull(void* c),就需要对 NULL(或者 0)进行强制类型转换:如此,才会成功调用我们预期的函数。

isnull( (void*)NULL );
// 或者
isnull( (void*)0 );

【 1. 基本用法 】

  • 由于 C++ 98 标准使用期间,NULL 已经得到了广泛的应用,出于兼容性的考虑,C++11 标准并没有对 NULL 的宏定义做任何修改,即 传统空指针NULL仍可用但是有BUG 。为了修正 C++ 存在的这一 BUG,C++ 标准委员会最终决定另其炉灶,在 C++11 标准中引入一个新关键字,即 nullptr。
  • nullptr_t 指针空值类型 是 C++11 新增加的数据类型。nullptr 是 nullptr_t 类型的右值常量,专用于初始化空类型指针,也就是说,nullptr 仅是该类型的一个已定义好可直接使用的实例对象 ,如果需要我们完全定义出多个同 nullptr 完全一样的实例对象。

【 2. nullptr 的应用 】

2.1 nullptr 解决 NULL 的遗留BUG

由于 nullptr 无法隐式转换为整形,而可以隐式匹配指针类型 ,因此执行结果和我们的预期相符。
总之在 C++11 标准下,相比 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 简单实例

不同类型的指针变量都可以使用 nullptr 来初始化,编译器分别将 nullptr 隐式转换成 int*、char* 以及 double* 指针类型。

int * a1 = nullptr;
char * a2 = nullptr;
double * a3 = nullptr;

到此这篇关于C++ 11 nullptr 空指针的文章就介绍到这了,更多相关C++ 11 nullptr 空指针内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++实现LeetCode(90.子集合之二)

    C++实现LeetCode(90.子集合之二)

    这篇文章主要介绍了C++实现LeetCode(90.子集合之二),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • c语言求1+2+...+n的解决方法

    c语言求1+2+...+n的解决方法

    本篇文章是对在c语言中求1+2+...+n的解决方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C++标准库中的Stack(堆栈)和Queue(队列)详解

    C++标准库中的Stack(堆栈)和Queue(队列)详解

    在C++标准模板库(STL)中,stack和queue是两种非常重要的容器适配器,这篇文章主要介绍了C++标准库中Stack(堆栈)和Queue(队列)的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-10-10
  • C语言学习笔记之VS2022安装使用教程

    C语言学习笔记之VS2022安装使用教程

    这篇文章主要介绍了C语言学习笔记之VS2022安装使用教程,在VS2022中,在使用scanf函数编译出错,本文给大家提到了解决方法,需要的朋友可以参考下
    2022-05-05
  • C++实现LeetCode(71.简化路径)

    C++实现LeetCode(71.简化路径)

    这篇文章主要介绍了C++实现LeetCode(71.简化路径),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • 深入C++浮点数无效值定义与判定的解决办法

    深入C++浮点数无效值定义与判定的解决办法

    本篇文章是对C++中浮点数无效值定义与判定进行了介绍,需要的朋友参考下
    2013-05-05
  • C++函数返回值缺失问题及解决

    C++函数返回值缺失问题及解决

    C++函数返回值缺失会导致未定义行为,引发逻辑错误、崩溃等风险,编译器通常仅警告而非强制报错,但可通过编译选项将其升级为错误,解决方案包括显式覆盖所有代码路径、启用严格检查、简化控制流,并注意main函数的隐式返回0例外
    2025-09-09
  • C语言编程入门必背的示例代码整理大全

    C语言编程入门必背的示例代码整理大全

    这篇文章主要为大家整理并介绍了C语言编程必背的示例代码大全,有需要的朋友可以借鉴参考下,希望能够有所帮助
    2021-11-11
  • C++ set的使用示例详解

    C++ set的使用示例详解

    序列式容器如vector、list等存储数据的逻辑结构为线性序列,元素的存储和访问是按位置顺序进行的,而关联式容器如set、map等,本文给大家介绍C++ set的使用示例详解,感兴趣的朋友一起看看吧
    2024-10-10
  • 使用udp发送>=128K的消息会报ENOBUFS的错误的解决方法

    使用udp发送>=128K的消息会报ENOBUFS的错误的解决方法

    在项目中选择了unix域的数据报套接口。在使用过程中碰到了如下,问题:发送<128K的消息时,客户、进程可以正常收发消息;发送>=128K的消息时,发送端(sendto)返回ENOBUFS的错误。下面小编来详细说下
    2019-05-05

最新评论