c++11 std - nullptr

本文通过一个简单的C++示例介绍了nullptr关键字的使用方法及其与0和NULL的区别。当函数参数为0或NULL时,编译器可能会将其当作整型处理,从而导致预期之外的行为。为了提高代码的可读性和避免潜在的错误,C++引入了nullptr来专门表示空指针,它能自动转换为目标指针类型。

测试代码:

#include <cstdlib>
#include <string>
#include <iostream>
#include <thread>
#include <array>

using namespace std;

void f(int test);
void f(void* test);

int main(int argc, char *argv[])
{
	f(nullptr);
	f(NULL);
	f(0);
	while(1);
    return EXIT_SUCCESS;
}
void f(int test)
{
    cout<<"int:test = "<<test<<endl;   
}

void f(void* test)
{
    cout<<"void*:test = "<<test<<endl;   
}

输出结果:

void*:test = 0
int:test = 0
int:test = 0

分析:

在实际应用过程中如果 f 函数 参数是0 或者NULL或被编译器默认的认为是int,如果想调用void f(void* test) 要加强制转换 (void*)0或(void*)NULL可以解决这个问题。

这样就会引起可读性变差,或者忘记加强制性转换直接引入了bug。

为了解决上面的问题C++标准引入了nullptr 关键字,实际上他是一个 const 的 void* 指针,他对任何其他指针复制都会自动强制的转化为对应的指针类型。

<think> 首先,用户的问题是:“我想了解C++中delete和nullptr的区别 请问C++中delete和nullptr的区别”。我需要基于提供的引用内容来回答。 回顾系统级指令: - 所有行内数学表达式必须使用 $...$ 格式。 - 独立公式必须使用 $$...$$ 格式并单独成段。 - LaTeX 语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识。 - 回答结构清晰,帮助用户逐步解决问题。 提供的引用: 1. [^1]: delete nullptr 不会产生额外性能损耗,性能等同于 if (ptr) delete ptr;。这是编译器优化。 2. [^2]: 释放内存后应将指针设为 nullptr 以避免悬挂指针。 3. [^3]: delete nullptr 不会报错,因为 free 和 delete 检查了 nullptr。 4. [^4]: delete ptr 释放了 ptr 指向的内存,但 ptr 本身仍存在;删除后设为 nullptr 以防止悬挂指针。 关键点: - delete 是操作符,用于释放动态分配的内存。 - nullptr 是空指针常量,用于表示指针不指向任何对象。 - 区别在于:delete 是动作(释放内存),nullptr 是值(设置指针为空)。 - 常见实践:delete ptr 后,设置 ptr = nullptr 以避免悬挂指针。 回答结构: 1. **介绍 delete 和 nullptr**:简要解释各自是什么。 2. **区别说明**:清晰对比两者的角色和用途。 3. **为什么需要设置 nullptr**:基于引用,解释悬挂指针的危险。 4. **性能方面**:提到 delete nullptr 的性能优化。 5. **生成相关问题**:结束时添加相关问题。 用中文回答: - 语言要自然、清晰。 - 引用时添加标识:[^1], [^2] 等。 生成相关问题: - 基于主题,如 C++ 内存管理、delete 的其他用法等。 最终回答框架: - 开头:直接回答问题。 - 主体:逐步解释。 - 结尾:相关问题。 </think> ### C++ 中 delete 和 nullptr 的区别 在 C++ 中,`delete` 和 `nullptr` 是在内存管理中常用的两个概念,但它们扮演的角色完全不同。以下将逐步解释它们的区别、用途和相互关系,确保回答清晰可靠。 1. **定义与基本角色** - `delete`:这是一个操作符(operator),用于释放动态分配的内存(即通过 `new` 分配的内存)。当调用 `delete ptr;` 时,它会销毁 `ptr` 指向的对象,并将该内存归还给系统[^4]。 - 例如:`int* ptr = new int(100); delete ptr;` 释放了 `ptr` 指向的整型内存。 - `nullptr`:这是一个空指针常量(C++11 引入),表示指针不指向任何对象。它用于将指针设置为“空”状态,避免无效引用[^2]。 - 例如:`ptr = nullptr;` 确保 `ptr` 不再是悬挂指针。 本质区别:`delete` 是**释放内存的动作**,而 `nullptr` 是**设置指针状态的赋值**。两者不是互斥的,而是经常配合使用以提高安全性。 2. **关键区别点** - **作用对象不同**: - `delete` 作用于指针指向的内存:它会清除该内存区域的内容,但指针变量本身(如 `ptr` 的地址)不会被删除。删除后,指针变成“悬挂指针”(dangling pointer),指向无效内存[^4]。 - `nullptr` 作用于指针变量本身:它只是改变指针的值,使其指向空地址(0x0),不涉及内存释放。 - **安全性影响**: - 如果不使用 `delete`,会导致内存泄漏(memory leak),因为分配的内存未被归还[^4]。 - 如果 `delete` 后不设置 `nullptr`,指针可能随机指向无效内存(空悬指针),后续意外使用(如 `*ptr = 10;`)会引发未定义行为(undefined behavior),如程序崩溃或数据损坏[^2][^4]。 - 正确做法通常是组合使用:`delete ptr; ptr = nullptr;` 这样既能释放内存,又能避免悬挂指针风险[^2][^4]。 3. **性能与编译器行为** - `delete nullptr` 是安全的操作:当指针已是 `nullptr` 时调用 `delete`,编译器会自动优化(类似于 `if (ptr) delete ptr;`),不会产生额外性能损耗或错误[^1][^3]。 - 例如:`delete nullptr;` 与 `if (ptr) delete ptr;` 在性能上等效(现代编译器如 GCC 或 Clang 均对此优化)[^1]。 - 相反,`delete` 非空指针时必须确保内存有效;否则可能触发异常或错误[^3]。 4. **代码示例对比** 以下代码演示关键行为: ```cpp #include <iostream> int main() { int* ptr = new int(100); // 动态分配内存 std::cout << "ptr 地址: " << ptr << std::endl; // 输出指向的内存地址 delete ptr; // 释放内存,但 ptr 变量本身未变 std::cout << "delete 后 ptr 地址: " << ptr << std::endl; // 可能指向随机地址(悬挂指针) ptr = nullptr; // 设置为空指针 std::cout << "设置 nullptr 后 ptr 地址: " << ptr << std::endl; // 输出 0(安全) delete nullptr; // 安全,无操作(编译器优化) return 0; } ``` - 输出说明:`delete ptr` 后,`ptr` 的地址不变(如 `0x7ffeebd8`),但其指向的内容无效;`ptr = nullptr` 将其重置为 `0x0`。 5. **最佳实践总结** - 总是配对使用:`delete` 后立即设置 `ptr = nullptr`,以防止悬挂指针[^2][^4]。 - `delete nullptr` 是冗余但安全的,编译器会优化掉,不影响性能[^1][^3]。 -C++11 后,优先使用 `nullptr` 而非旧式 `NULL` 或 `0`,以增强类型安全和可读性。 通过以上步骤,清楚区分了 `delete`(内存释放操作)和 `nullptr`(指针状态设置)。两者协同工作能显著提升代码健壮性[^1][^2][^3][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值