【C++ 11】nullptr 空指针

news/2024/12/22 0:21:18/

文章目录

  • 【 0. 问题背景 】
    • 0.1 野指针和悬空指针
    • 0.2 传统空指针 NULL
    • 0.3 传统空指针的局限性
  • 【 1. 基本用法 】
  • 【 2. nullptr 的应用 】
    • 2.1 nullptr 解决 NULL 的遗留BUG
    • 2.2 简单实例

【 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;

http://www.ppmy.cn/news/1536418.html

相关文章

23.1 k8s监控中标签relabel的应用和原理

本节重点介绍 : relabel的源码在 7.7节做过详细的解读强大的relabel能力 在k8s中的应用 应用1&#xff1a; labelmap 在采集cadvisor指标时 对服务发现标签key名字截取应用2&#xff1a; 采集pod自定义指标中replace 和 keep的应用应用3&#xff1a; k8s服务组件采集时的endpo…

如何高效使用Prompt与AI大模型对话

一、如何与人工智能对话 在人工智能的世界里&#xff0c;提示词&#xff08;Prompt&#xff09;就像是一把钥匙&#xff0c;能够解锁AI智能助手的潜力&#xff0c;帮助你更高效地获取信息、解决问题。但如何正确使用这把钥匙&#xff0c;却是一门艺术。本文将带你了解提示词的…

WPF入门教学二十三 自定义控件开发

在WPF&#xff08;Windows Presentation Foundation&#xff09;中&#xff0c;自定义控件开发是一项强大的功能&#xff0c;它允许开发者根据特定需求创建独特的用户界面元素。自定义控件可以是简单的用户控件&#xff0c;也可以是更复杂的继承自现有控件的自定义控件。以下是…

GTest测试框架介绍

文章目录 GTest使用简单的宏断言事件机制全局使用样例局部使用样例 GTest是谷歌发布的一个跨平台的单元测试框架,主要是为了在不同平台上编写的C单元测试而生成的 提供了丰富的断言,致命和非致命的判断,参数化 GTest使用 简单的宏断言 断言分两类 一类是ASSERT系列的,如果当…

通讯方面的数据,人工智能 机器学习的时候,因为数字都接近于一,数据归一化的一种方法,做了一个简化版本的Z-score标准化

这个表达式实现了一种形式的数据归一化&#xff0c;它将张量x中的每个元素除以x的标准差的估计值。这种处理方式可以使得变换后的数据具有单位标准差&#xff08;假设数据已经是零均值或者在计算过程中考虑了均值&#xff09;。具体来说&#xff0c;它是基于以下步骤进行的&…

《OpenCV 计算机视觉》—— 视频背景建模

文章目录 一、背景建模的目的二、背景建模的方法三、背景建模的步骤四、注意事项五、代码实现 一、背景建模的目的 视频背景建模的主要目的是从视频序列中提取出静态背景&#xff0c;以便将动态的前景对象与静态的背景进行分离。这有助于进一步分析和处理视频内容&#xff0c;…

java8 双冒号(::)使用方法

双冒号&#xff08;::&#xff09;运算符是跟函数式接口相关的运算符&#xff0c;作为函数式接口的赋值操作。 双冒号用于静态方法 使用方法&#xff1a;将类的静态方法赋值给一个函数式接口&#xff0c;静态方法的参数个数、类型要跟函数式的接口一致。调用这个函数式接口就…

202408第十五届蓝桥杯青少组省赛C++中级组题解

202408第十五届蓝桥杯青少组省赛C++中级组题解 单选题 1、定义 char a[]="hello\nworld",执行 cout<<a,输出结果是(B) A、helloworld B、hello world C、 hellonworld D、 hello\nworld 解析:\n输出时会换行。 2、 的结果是(C)。 A、 B、