使用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]的实际执行顺序是:
- 先计算
(test_2d + n)[a],等价于*(test_2d + n + a),这已经超出了原本分配的3个二维数组的范围(当n+a >=3时) - 再取
[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
相关产品推荐
相关产品推荐

