如何在C ++中正确使用动态分配的多维数组

时间:2015-12-03 22:55:43

标签: c++ arrays dynamic-arrays

如何在C ++中定义动态多维数组?例如,二维数组?我尝试使用指针指针,但不知怎的,它失败了。

1 个答案:

答案 0 :(得分:7)

首先应该意识到C ++中没有多维数组支持,无论是作为语言功能还是标准库。因此,我们可以做的任何事情都是对它的一些模仿。我们怎样才能模拟二维整数数组呢?以下是不同的选择,从最不适合到最合适。

不正当的尝试#1。使用指向指针

的指针

如果使用指向该类型的指针模拟数组,那么应该使用指向该类型的指针来模拟二维数组吗?像这样的东西?

int** dd_array = new int[x][y];

这是一个编译器错误。没有new [][]运算符,所以编译器很乐意拒绝。好吧,那怎么样?

int** dd_array = new int*[x];
dd_array[0][0] = 42;

编译。在执行时,它会因令人不快的消息而崩溃。出了点问题,但是什么?当然!我们确实为第一个指针分配了内存 - 它现在指向一个内存块,它包含指向int的x指针。但我们从未初步化过这些指针!我们再试一次。

int** dd_array = new int*[x];
for (std::size_t i = 0; i < x; ++i)
   dd_array[i] = new int[y];

dd_array[0][0] = 42;

这不会产生任何编译错误,并且程序在执行时不会崩溃。任务完成?没那么快。请记住,每次我们拨打new时,我们必须呼叫delete。那么,你走了:

for (std::size_t i = 0; i < x; ++i)
    delete dd_array[i];
delete dd_array;

现在,那太可怕了。语法很丑,手动管理所有这些指针......不。让我们全力以赴,做些更好的事情。

减少不正当的尝试#2。使用std::vector

std::vector

确定。我们知道在C ++中我们不应该真正使用手动内存管理,这里有一个方便的std::vector。那么,我们可以做到这一点吗?

std::vector<std::vector<int> > dd_array;

显然,这还不够 - 我们从未指定过这些数组的大小。所以,我们需要这样的东西:

std::vector<std::vector<int> > dd_array(x);
for(auto&& inner : dd_array)
    inner.resize(y);

dd_array[0][0] = 42;

那么,现在好吗?没那么多。首先,我们仍然有这个循环,它是一个痛苦的眼睛。更重要的是,我们严重损害了我们的应用程序的性能。由于每个单独的内部向量都是独立分配的,所以循环如下:

int sum = 0;
for (auto&& inner : dd_array)
    for (auto&& data : inner)
       sum += data;

将导致对许多独立分配的内部向量进行迭代。由于CPU只会缓存连续内存,因此不能完全缓存那些小的独立向量。当你无法缓存时会伤害性能!

那么,我们该怎么做呢?

正确的尝试#3 - 单维!

我们根本就没有!当情境需要二维向量时,我们只是以编程方式使用一维向量并使用偏移量访问它的元素!我们就是这样做的:

vector<int> dd_array(x * y);
dd_array[k * x + j] = 42; // equilavent of 2d dd_array[k][j]

这给了我们精彩的语法,表现和所有的荣耀。为了让我们的生活稍微好一点,我们甚至可以在一维矢量上构建一个适配器 - 但这是留给作业的。