为啥二维动态数组有初始值?

Posted

技术标签:

【中文标题】为啥二维动态数组有初始值?【英文标题】:Why 2d dynamic array has initial values?为什么二维动态数组有初始值? 【发布时间】:2015-07-21 21:51:04 【问题描述】:

我正在尝试使用 new 运算符来分配二维数组。这是我的函数 new2d。

int** new2d(int r, int c)

    int **t = new int*[r];
    for(int i = 0; i < r; i++)
        t[i] = new int[c];
    return t;

我很确定这是正确的方法。但是,当我尝试像下面这样打印数组时

int **a = new2d(5, 9);
for(int i = 0; i < 5; i++)

    for(int j = 0; j < 9; j++)
    
        cout << a[i][j] << " ";
    
    cout << endl;

它以随机 13,10,7... 给出这个奇怪的输出...

0 0 0 0 13 0 0 0 0 
0 0 0 0 10 0 0 0 0 
0 0 0 0 7 0 0 0 0 
0 0 0 0 4 0 0 0 0 
0 0 0 0 0 0 0 0 0 

为什么会这样?

【问题讨论】:

您从未初始化每一行中的值。您看到的数据是不确定的。将此:new int[c]; 更改为:new int[c]();。更好的是,将整个内容更改为std::vector&lt;std::vector&lt;int&gt;&gt; a(5, std::vector&lt;int&gt;(9)); 众所周知new 不需要为您初始化分配的内存。如果是这样,并且您想要的不是默认初始化,new 将为您做出决定,只会浪费您的时间。但是,通过在目标对象上特意指定构造函数,您可以让 执行它自己定义的初始化。 我强烈建议按照 WhozCraig 所说的去做。使用原始指针是有风险的。 ^ 特别是当 C++ 提供了这么多更好的解决方案时。 知道了,谢谢大家!但是新的 int[c]( ); 是什么?为了? 【参考方案1】:

默认初始化可能导致不确定的值。引用自http://en.cppreference.com/w/cpp/language/default_initialization

默认初始化在三种情况下执行:

1) 声明具有自动、静态或线程本地存储持续时间的变量时没有初始化器。

2) 当具有动态存储持续时间的对象由不带初始化程序的 new 表达式创建时,或当对象由初始化程序由一对空括号组成的 new 表达式创建时(C++03 前) .

3) 当基类或非静态数据成员未在构造函数初始化程序列表中提及并且该构造函数被调用时。

默认初始化的效果是:

如果 T 是非 POD(C++11 之前)类类型,则考虑构造函数并针对空参数列表进行重载决策。

调用选择的构造函数(默认构造函数之一)为新对象提供初始值。

如果 T 是数组类型,则数组的每个元素都是默认初始化的。 否则,什么都不做:具有自动存储持续时间的对象(及其子对象)被初始化为不确定的值。

在你的情况下,你满足条件 2。

【讨论】:

【参考方案2】:

您似乎在t[i] = new int[c]; 之后没有初始化数组 然而,这不是创建数组的最佳方式。这是一个更大的讨论 How do I declare a 2d array in C++ using new?

嗯。通常最好使用诸如

之类的方法
int *array = new int[sizeX*sizeY];

ary[i][j] 然后被重写为array[i*sizeY+j]

是的,最好阅读大讨论,更好地理解 + 和 -

【讨论】:

说“这不是最佳的”意味着有更好的方法。链接到对几种替代方法的大型讨论并不能告诉我们您认为哪种方法更好。这没有多大帮助。

以上是关于为啥二维动态数组有初始值?的主要内容,如果未能解决你的问题,请参考以下文章

指针与数组——二级指针 数组初始化 数组打印 动态二维数组

为啥我们在传递动态二维数组时不需要列数?

动态二维数组。为啥是分段错误?

JAVASE 数组: 一维数组二维数组动态数组静态数组

在 C++ 中初始化动态二维数组

Java中一维,二维数组的静态和动态初始化