我需要创建一个大型的二维对象数组。我已经阅读了该网站上的一些相关问题以及其他有关 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 个成员函数。
I need to create a large two dimensional array of objects. I've read some related questions on this site and others regarding multi_array, matrix, vector, etc, but haven't been able to put it together. If you recommend using one of those, please go ahead and translate the code below.
Some considerations:
- The array is somewhat large (1300 x 1372).
- I might be working with more than one of these at a time.
- I'll have to pass it to a function at some point.
- Speed is a large factor.
The two approaches that I thought of were:
Pixel pixelArray[1300][1372];
for(int i=0; i<1300; i++) {
for(int j=0; j<1372; j++) {
pixelArray[i][j].setOn(true);
...
}
}
and
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);
...
}
}
What's the right approach/syntax here?
Edit:
Several answers have assumed Pixel
is small - I left out details about Pixel
for convenience, but it's not small/trivial. It has ~20 data members and ~16 member functions.
发布评论
评论(6)
您的第一种方法在堆栈上分配所有内容,这在其他方面都很好,但当您尝试分配太多堆栈时会导致堆栈溢出。现代操作系统上的限制通常约为 8 MB,因此无法在堆栈上分配 1300 * 1372 个元素的数组。
第二种方法在堆上分配 1300 * 1372 个元素,这对于分配器来说是一个巨大的负载,分配器将多个链接列表保存到已分配和可用内存块。这也是一个坏主意,尤其是因为 Pixel 看起来相当小。
我要做的是:
这样你就可以在堆上分配一大块内存。堆栈很高兴,堆分配器也很高兴。
Your first approach allocates everything on stack, which is otherwise fine, but leads to stack overflow when you try to allocate too much stack. The limit is usually around 8 megabytes on modern OSes, so that allocating arrays of 1300 * 1372 elements on stack is not an option.
Your second approach allocates 1300 * 1372 elements on heap, which is a tremendous load for the allocator, which holds multiple linked lists to chunks of allocted and free memory. Also a bad idea, especially since Pixel seems to be rather small.
What I would do is this:
This way you allocate one large chunk of memory on heap. Stack is happy and so is the heap allocator.
如果您想将其传递给函数,我会投票反对使用简单数组。请考虑:
这不包含任何尺寸信息。您可以通过单独的参数传递大小信息,但我宁愿使用 std::vector 之类的东西。当然,这需要您定义寻址约定(行优先或列优先)。
另一种选择是 std::vector >,其中每一层向量都是一个数组维度。优点:像pixelArray[x][y]中的双下标可以工作,但是创建这样的结构很繁琐,复制成本更高,因为它是针对每个包含的向量实例而不是使用简单的memcpy进行复制,并且包含在顶级向量不一定具有相同的大小。
这些基本上是您使用标准库的选项。正确的解决方案是类似于二维的 std::vector 。我想到的是数值库和图像处理库,但矩阵和图像类很可能仅限于其元素中的原始数据类型。
编辑:忘记澄清以上所有内容都只是争论。最后,必须考虑您的个人品味和背景。如果您独自参与该项目,向量加上定义和记录的寻址约定应该足够好了。但是,如果您在一个团队中,并且很可能有人会忽略已记录的约定,则级联向量对向量结构可能会更好,因为繁琐的部分可以通过辅助函数来实现。
If you want to pass it to a function, I'd vote against using simple arrays. Consider:
This does not contain any size information. You could pass the size info via separate arguments, but I'd rather use something like std::vector<Pixel>. Of course, this requires that you define an addressing convention (row-major or column-major).
An alternative is std::vector<std::vector<Pixel> >, where each level of vectors is one array dimension. Advantage: The double subscript like in pixelArray[x][y] works, but the creation of such a structure is tedious, copying is more expensive because it happens per contained vector instance instead of with a simple memcpy, and the vectors contained in the top-level vector must not necessarily have the same size.
These are basically your options using the Standard Library. The right solution would be something like std::vector with two dimensions. Numerical libraries and image manipulation libraries come to mind, but matrix and image classes are most likely limited to primitive data types in their elements.
EDIT: Forgot to make it clear that everything above is only arguments. In the end, your personal taste and the context will have to be taken into account. If you're on your own in the project, vector plus defined and documented addressing convention should be good enough. But if you're in a team, and it's likely that someone will disregard the documented convention, the cascaded vector-in-vector structure is probably better because the tedious parts can be implemented by helper functions.
我不确定你的 Pixel 数据类型有多复杂,但也许这样的东西适合你?:
std::fill(array, array+100, 42); // 将数组中的每个值设置为 42
参考:
使用一个默认值初始化普通数组
I'm not sure how complicated your Pixel data type is, but maybe something like this will work for you?:
std::fill(array, array+100, 42); // sets every value in the array to 42
Reference:
Initialization of a normal array with one default value
查看 Boost 的通用图像库。
Check out Boost's Generic Image Library.
我个人的偏好是使用 std::vector
My personal peference would be to use std::vector
虽然我不一定将其设为结构,但这演示了我将如何存储和访问数据。如果 Pixel 相当大,您可能需要使用 std::deque 代替。
While I wouldn't necessarily make this a struct, this demonstrates how I would approach storing and accessing the data. If Pixel is rather large, you may want to use a std::deque instead.