在c ++中声明和初始化(大)二维对象数组的正确方法是什么?

时间:2011-07-29 17:51:20

标签: c++ multidimensional-array initialization declaration

我需要创建一个大的二维对象数组。我已经在这个网站上阅读了一些关于multi_array,matrix,vector等的相关问题,但是还没有把它放在一起。如果您建议使用其中之一,请继续翻译下面的代码。

一些注意事项:

  • 阵列有点大(1300 x 1372)。
  • 我可能一次只使用其中一种以上。
  • 我必须在某个时候把它传递给一个函数。
  • 速度是一个很重要的因素。

我想到的两种方法是:

Pixel pixelArray[1300][1372];
for(int i=0; i<1300; i++) {
    for(int j=0; j<1372; j++) {
        pixelArray[i][j].setOn(true);
        ...
    }
}

Pixel* pixelArray[1300][1372];
for(int i=0; i<1300; i++) {
    for(int j=0; j<1372; j++) {
        pixelArray[i][j] = new Pixel();
        pixelArray[i][j]->setOn(true);
        ...
    }
}

这里的正确方法/语法是什么?

修改

有几个答案假设Pixel很小 - 为方便起见,我省略了有关Pixel的详细信息,但它并不小/小。它有大约20个数据成员和~16个成员函数。

6 个答案:

答案 0 :(得分:4)

你的第一种方法是在堆栈上分配所有东西,否则很好,但是当你尝试分配太多堆栈时会导致堆栈溢出。现代操作系统的限制通常约为8兆字节,因此在堆栈上分配1300 * 1372个元素的数组不是一种选择。

你的第二种方法在堆上分配1300 * 1372个元素,这对分配器来说是一个巨大的负载,它将多个链表保存到分配的和可用内存块中。也是一个坏主意,特别是因为Pixel看起来很小。

我要做的是:

Pixel* pixelArray = new Pixel[1300 * 1372];
for(int i=0; i<1300; i++) {
    for(int j=0; j<1372; j++) {
        pixelArray[i * 1372 + j].setOn(true);
        ...
    }
}

这样就可以在堆上分配一大块内存。堆栈很高兴,堆分配器也是如此。

答案 1 :(得分:0)

如果你想将它传递给一个函数,我会反对使用简单的数组。考虑:

void doWork(Pixel array[][]);

这不包含任何尺寸信息。你可以通过单独的参数传递大小信息,但我宁愿使用像std :: vector&lt; Pixel&gt;这样的东西。当然,这需要您定义寻址约定(行主要或列主要)。

替代方案是std :: vector&lt; std :: vector&lt; Pixel&gt; &gt;,其中每个向量级别是一个数组维度。优点:像pixelArray [x] [y]中的双下标有效,但是这种结构的创建是繁琐的,复制更加昂贵,因为它发生在每个包含的矢量实例而不是简单的memcpy中,并且包含在顶级向量不一定必须具有相同的大小。

这些基本上是您使用标准库的选项。正确的解决方案就像std :: vector有两个维度。我想到了数值库和图像处理库,但矩阵和图像类很可能仅限于其元素中的原始数据类型。

编辑:忘了明确上述所有内容都只是参数。最后,您的个人品味和背景将被考虑在内。如果您在项目中独立,那么矢量加定义和记录的寻址约定应该足够好。但是如果你在一个团队中,并且很可能有人会忽视所记录的约定,那么级联矢量矢量结构可能更好,因为繁琐的部分可以通过辅助函数来实现。

答案 2 :(得分:0)

我不确定您的Pixel数据类型有多复杂,但是这样的事情对您有用吗?:

std :: fill(array,array + 100,42); //将数组中的每个值设置为42

参考: Initialization of a normal array with one default value

答案 3 :(得分:0)

查看Boost的通用图像库。

gray8_image_t pixelArray;
pixelArray.recreate(1300,1372);
for(gray8_image_t::iterator pIt = pixelArray.begin(); pIt != pixelArray.end(); pIt++) {
    *pIt = 1;
}

答案 4 :(得分:0)

虽然我不一定会将其作为结构,但这演示了我如何处理存储和访问数据。如果Pixel相当大,您可能需要使用std :: deque。

struct Pixel2D {
  Pixel2D (size_t rsz_, size_t csz_) : data(rsz_*csz_), rsz(rsz_), csz(csz_) {
    for (size_t r = 0; r < rsz; r++)
    for (size_t c = 0; c < csz; c++)
      at(r, c).setOn(true);
  }
  Pixel &at(size_t row, size_t col) {return data.at(row*csz+col);}
  std::vector<Pixel> data;
  size_t rsz;
  size_t csz;
};

答案 5 :(得分:0)

我个人的偏好是使用std :: vector

typedef  std::vector<Pixel>       PixelRow;
typedef  std::vector<PixelRow>    PixelMatrix;

PixelMatrix   pixelArray(1300, PixelRow(1372, Pixel(true)));
      //                 ^^^^           ^^^^  ^^^^^^^^^^^
      //                 Size 1         Size 2   default Value