必须用 nullptr 替换 NULL 和 0:它是类型安全的空指针字面量,可避免重载歧义、模板推导失败及隐式转整数;禁止 if(!ptr) 或 ptr==0/NULL;new 默认抛异常不返回 nullptr,仅 nothrow 版需检查。

用 nullptr 替换 NULL 和 0 是必须的
在 C++11 及之后,nullptr 是唯一类型安全的空指针字面量。用 NULL(本质是整数 0 或 #define NULL 0)或直接写 0,会导致函数重载歧义、模板推导失败,甚至隐式转成整数参与运算。
常见错误现象:void foo(int); void foo(char*); foo(NULL); 调用的是 foo(int),不是你想要的指针版本。
- 所有新代码中,初始化、比较、返回空指针时,统一用
nullptr - 老代码迁移时,全局搜索
NULL和裸0(在指针上下文中),逐个替换;但注意别误改整数字面量 -
nullptr的类型是std::nullptr_t,能被任何指针类型隐式转换,但不会转成整数
判断指针是否为空必须显式比较 ptr == nullptr
野指针的本质不是“空”,而是“指向已释放/未初始化/非法地址”。所以 nullptr 只能帮你拦住“明确为空”的情况,不能自动捕获野指针。但至少让“空检查”这件事变得可靠。
使用场景:函数入口校验、智能指针释放后置空、容器中指针元素清理前判断。
立即学习“C++免费学习笔记(深入)”;
- 禁止写
if (!ptr)—— 虽然它通常有效,但可读性差,且对自定义类型(如某些代理指针)可能触发意外转换操作符 - 禁止写
if (ptr == 0)或if (ptr == NULL)—— 类型不匹配警告在严格编译模式下会报错(比如-Wzero-as-null-pointer-constant) - 推荐风格:
if (ptr != nullptr) { ... },语义清晰,无歧义,编译器友好
动态分配后立即检查 new 是否返回 nullptr?不用,但得知道它不会
new 默认抛出 std::bad_alloc,根本不会返回 nullptr。所以写 if (p == nullptr) 检查 new 结果是无效且误导的。
除非你用了 nothrow 版本:int* p = new(std::nothrow) int[1000];,这时才可能返回 nullptr。
- 默认
new:异常安全优先,不需空检查,但要配try/catch -
new(std::nothrow):返回nullptr表示失败,此时必须检查 —— 但要注意,这绕过了 RAII 习惯,容易漏清理 - 更现代的做法:用
std::make_unique或std::make_shared,它们内部用默认new,失败即抛异常,无需手动判空
智能指针 + nullptr 才算真正降低野指针风险
nullptr 本身不防止野指针,它只是让“空”这个状态更干净。真正减少野指针,得靠所有权管理。
使用场景:资源生命周期不确定、多处共享、需要自动释放的指针。
-
std::unique_ptr构造时可传nullptr,移动后原指针自动变nullptr,避免悬垂 -
std::shared_ptr赋值为nullptr会析构所管理对象(若无其他引用),比裸指针delete后忘记置空安全得多 - 切忌混合使用:
std::shared_ptr<int> p(new int(42));</int>是危险的 —— 若new成功但构造shared_ptr时异常,内存泄漏;应改用std::make_shared<int>(42)</int>
野指针最难防的其实是“释放后仍被持有”,而 nullptr 只管“初始为空”或“主动置空”这种最表层的情况。真要压住风险,得从所有权语义入手,不是光换一个字面量就能解决的。











