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

使用new初始化的空3D double数组打印随机值,是否存在错误?

问题描述

这是我的第一篇帖子,若论坛操作有不当之处请告知。以下是我的代码:

double (*test_2d)[3][3] = new double[3][3][3];

for(int a = 0; a < 3; a++)
{
    for(int b = 0; b < 3; b++)
    {
        std::cout<<*(test_2d+0)[a][b]<<std::endl; //dereference to get 2d array from pointer
    };
};

for(int a = 0; a < 3; a++)
{
    for(int b = 0; b < 3; b++)
    {
        std::cout<<*(test_2d+1)[a][b]<<std::endl; //dereference to get 2d array from pointer+1
    };
};

for(int a = 0; a < 3; a++)
{
    for(int b = 0; b < 3; b++)
    {
        std::cout<<*(test_2d+2)[a][b]<<std::endl; //dereference to get 2d array from pointer+2
    };
};

打印时部分值极大,如截图所示。我的核心问题:使用new初始化(double)多维数组时,值是否应默认设为nan或0.00?截图是否说明我数组索引错误?
此问题源于我正在开发的模板递归项目,为简化问题编写了上述代码,想了解new对内存值的定义规则及是否存在索引错误。


解答

1. new初始化多维数组的默认值规则

  • 默认的new(不带括号或大括号的初始化语法)分配**基本类型(如double、int)**的数组时,不会初始化内存。分配的内存区域会保留之前遗留的垃圾数据,这些值是随机的,可能是极大数、极小数或其他无意义的值,既不是0.0也不是NaN。
  • 如果需要将数组元素初始化为默认值(对于double就是0.0),需要使用值初始化语法:
    // 两种写法都可以,效果一致
    double (*test_2d)[3][3] = new double[3][3][3]();
    // 或者
    double (*test_2d)[3][3] = new double[3][3][3]{};
    

2. 代码中的索引错误问题

你代码里的元素访问方式存在运算符优先级导致的错误:
[]的优先级高于*和+,所以*(test_2d + n)[a][b]的实际执行顺序是:

  1. 先计算(test_2d + n)[a],等价于*(test_2d + n + a),这已经超出了原本分配的3个二维数组的范围(当n+a >=3时)
  2. 再取[b]得到一个一维数组指针,最后解引用*获取元素
    这种越界访问会读取到内存中的垃圾数据,就是你看到的极大值。

正确的访问方式:
先解引用test_2d + n得到对应的二维数组,再用下标访问元素:

// 访问第n个3x3数组的[a][b]元素
std::cout << (*(test_2d + n))[a][b] << std::endl;

或者更简洁的数组式访问(因为test_2d本身可以当作指向二维数组的数组指针,test_2d[n]就是第n个二维数组):

std::cout << test_2d[n][a][b] << std::endl;

用这种方式就不会出现越界问题,读取的都是你分配的内存区域内的数据。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 17:51:45