我需要创建一个大的二维对象数组。我在这个网站上读过一些相关的问题,其他关于multi_array,矩阵,矢量等,但还没有能够把它放在一起。如果您推荐使用其中之一,请继续翻译下面的代码。
一些注意事项:
- 数组有点大(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个成员函数。
您的第一种方法在堆栈上分配所有内容,这在其他方面很好,但是当您试图分配过多的堆栈时,会导致堆栈溢出。在现代操作系统上,限制通常在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);
...
}
}
这种方式可以在堆上分配一大块内存。
如果你想把它传递给一个函数,我反对使用简单数组。考虑:
void doWork(Pixel array[][]);
不包含任何大小信息。您可以通过单独的参数传递大小信息,但我宁愿使用类似std::vector
可以选择std::vector
这些基本上是您使用标准库的选项。正确的解决方案应该是类似于二维的std::vector。我们会想到数值库和图像处理库,但是矩阵类和图像类很可能被限制为元素中的基本数据类型。
编辑:忘了说明上面的所有内容都只是参数。最后,你的个人品味和语境也要考虑进去。如果你是一个人在项目中,向量加上定义和文档的寻址约定应该是足够好的。但是,如果您是在一个团队中,并且很可能有人会忽略文档约定,那么级联向量中向量结构可能更好,因为繁琐的部分可以通过辅助函数实现。
我不确定你的Pixel数据类型有多复杂,但也许这样的东西会为你工作?:
std::fill(array, array+ 100,42);//设置数组中的每个值为42
参考:初始化具有一个默认值的普通数组
查看Boost的通用图像库。
gray8_image_t pixelArray;
pixelArray.recreate(1300,1372);
for(gray8_image_t::iterator pIt = pixelArray.begin(); pIt != pixelArray.end(); pIt++) {
*pIt = 1;
}
我个人倾向于使用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
虽然我不一定要让它成为一个结构体,但这演示了我将如何存储和访问数据。如果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;
};