You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GCC中nullptr异常行为探究:是否属于编译器Bug?

关于C++中new(nothrow)内存分配与nullptr布尔转换的疑问

我正在学习一段刻意编写的错误程序,目前还在深入理解阶段,不想带着误解继续。

测试代码

我在测试new分配内存时遇到了意外行为,编写了如下代码进行演示:

#include <iostream>
#include <new>

using namespace std;

int main()
{
    // 检查内存分配失败时是否会被赋值为nullptr
    int i = 2000000000; // 在long类型取值范围内
    int * p2 = new (nothrow) int[i];

    cout << "Allocation innappropriate amount of memory and getting nullptr?" << endl << endl;
    cout << "Pointer address: " << p2 << " --- Value at pointer address: " << *p2 << endl << endl;

    if(p2)
    {
        cout << "True - Pointer address: " << p2 << " --- Value at pointer address: " << *p2 << endl << endl << endl;
    }
    else
    {
        cout << "False -Pointer address: " << p2 << " --- Value at pointer address: " << *p2 << endl << endl << endl;
    }

    // 检查GCC中nullptr的表现
    int * p1 = nullptr;
    cout << "Assigning nullptr to pointer varialble." << endl << endl;

    if(p1)
    {
        cout << "True - Pointer address: " << p1 << " --- Value at pointer address: " << *p1 << endl << endl << endl;

    }
    else
    {
        cout << "False -Pointer address: " << p1 << " --- Accessing value would cause error!" << endl << endl << endl;
    }

}

程序输出

Allocation innappropriate amount of memory and getting nullptr?

Pointer address: 0x1f70783e040 --- Value at pointer address: 0

True - Pointer address: 0x1f70783e040 --- Value at pointer address: 0


Assigning nullptr to pointer varialble.

False -Pointer address: 0 --- Accessing value would cause error!



Process returned 0 (0x0)   execution time : 0.096 s
Press any key to continue.

我的疑问

我发现第二部分中,按标准无需解引用指针即可进行布尔测试,但实际结果与预期不符。请问这是对C++标准的不同解读,还是GCC的Bug?


解答

  1. nullptr的布尔转换完全符合标准
    C++标准明确规定,nullptr(类型为nullptr_t)可以隐式转换为bool,转换结果为false;任何非空指针转换为bool的结果都是true。你第二部分的代码中,p1被赋值为nullptr,所以if(p1)等价于判断static_cast<bool>(p1),结果为false,进入else分支输出对应内容,这完全符合标准,既不是GCC的Bug,也不存在标准解读差异。

  2. 第一部分内存分配的行为说明
    你分配了20亿个int,总内存大小为2000000000 * sizeof(int)(通常为8GB左右)。如果你的系统是64位,拥有足够的虚拟内存空间,new(nothrow)会成功分配内存,返回非空指针,此时if(p2)为true是正确的。你看到*p2的值为0,是因为new(nothrow)不会初始化分配的内存,这个0是内存中的随机残留值,并非初始化结果。如果内存分配失败,new(nothrow)才会返回nullptr,此时if(p2)会进入else分支,但你的当前环境中分配成功了,所以行为符合预期。

  3. 代码中的风险点
    第一部分代码存在严重问题:如果new(nothrow)真的返回nullptr,你直接解引用*p2会触发未定义行为。正确的做法是先检查指针是否非空,再进行解引用操作。


内容的提问来源于stack exchange,提问作者WackEyedWanderer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 21:35:38