在 C++ 中使用扁平数组语法,崩溃取决于 width/height
Using the flattened array syntax in C++, crashes depending on width/height
我已经阅读了很多 SO 和 cplusplus.com 中的文章,并决定尝试模拟 2D 和 3D 的扁平化 1D 数组。
我设法得到一个原型来处理一些值,但索引有问题,必须是公式。我所做的只是从不同的地方复制公式并应用于代码。这是:
#include <iostream>
using namespace std;
int main(void)
{
float *flat_2d_array, *flat_3d_array;
int width, height, depth, counter;
counter = 1;
width = 2;
height = 3;
depth = 4;
flat_2d_array = new float[width * height];
flat_3d_array = new float[width * height * depth];
// 2D part, works fine
for(int x = 0; x < width; x++)
for(int y = 0; y < height; y++)
flat_2d_array[y * width + x] = counter++;
for(int x = 0; x < width; x++)
for(int y = 0; y < height; y++)
cout << "Element [" << x << "]" << "[" << y << "] = " << flat_2d_array[y * width + x] << endl;
cout << endl;
// Resets the counter and runs the 3D part
counter = 1;
for(int x = 0; x < width; x++)
for(int y = 0; y < height; y++)
for(int z = 0; z < depth; z++)
flat_3d_array[z * height * depth + y * depth + x] = counter++;
for(int x = 0; x < width; x++)
for(int y = 0; y < height; y++)
for(int z = 0; z < depth; z++)
cout << "Element [" << x << "]" << "[" << y << "]" << "[" << z << "] = " << flat_3d_array[z * height * depth + y * depth + x] << endl;
delete[] flat_2d_array;
delete[] flat_3d_array;
return 0;
}
它只是声明了一些变量,为数组分配内存,在 for() 循环中用计数器填充它们并打印元素,然后释放内存。
如果你 copy/paste 它会按原样编译并且 运行 没问题。
但是,如果你把width改成3,height改成2,然后编译运行,它会在3D部分的元素[2][1][3]之后崩溃。
所以我用于 3D 的这个公式似乎存在索引问题:
3d_array[ X ][ Y ][ Z ] == flat_3d_array[ Z * height * depth + Y * depth + X ]
你们能看出哪里不对吗?
Can you guys see anything incorrect?
是的,您的公式应该改为:
z * height * width + y * width + x
或更高效的形式:
( z * height + y ) * width + x
并且你应该在 x
内部进行循环,否则你将迭代 CPU 缓存。
要明确:在 x
内部进行循环不会影响程序的正确性,它会使程序更高效(包括二维数组上的迭代)。您的程序崩溃是因为您使用错误的公式计算 3d 数组的线性索引。
我已经阅读了很多 SO 和 cplusplus.com 中的文章,并决定尝试模拟 2D 和 3D 的扁平化 1D 数组。 我设法得到一个原型来处理一些值,但索引有问题,必须是公式。我所做的只是从不同的地方复制公式并应用于代码。这是:
#include <iostream>
using namespace std;
int main(void)
{
float *flat_2d_array, *flat_3d_array;
int width, height, depth, counter;
counter = 1;
width = 2;
height = 3;
depth = 4;
flat_2d_array = new float[width * height];
flat_3d_array = new float[width * height * depth];
// 2D part, works fine
for(int x = 0; x < width; x++)
for(int y = 0; y < height; y++)
flat_2d_array[y * width + x] = counter++;
for(int x = 0; x < width; x++)
for(int y = 0; y < height; y++)
cout << "Element [" << x << "]" << "[" << y << "] = " << flat_2d_array[y * width + x] << endl;
cout << endl;
// Resets the counter and runs the 3D part
counter = 1;
for(int x = 0; x < width; x++)
for(int y = 0; y < height; y++)
for(int z = 0; z < depth; z++)
flat_3d_array[z * height * depth + y * depth + x] = counter++;
for(int x = 0; x < width; x++)
for(int y = 0; y < height; y++)
for(int z = 0; z < depth; z++)
cout << "Element [" << x << "]" << "[" << y << "]" << "[" << z << "] = " << flat_3d_array[z * height * depth + y * depth + x] << endl;
delete[] flat_2d_array;
delete[] flat_3d_array;
return 0;
}
它只是声明了一些变量,为数组分配内存,在 for() 循环中用计数器填充它们并打印元素,然后释放内存。
如果你 copy/paste 它会按原样编译并且 运行 没问题。 但是,如果你把width改成3,height改成2,然后编译运行,它会在3D部分的元素[2][1][3]之后崩溃。 所以我用于 3D 的这个公式似乎存在索引问题:
3d_array[ X ][ Y ][ Z ] == flat_3d_array[ Z * height * depth + Y * depth + X ]
你们能看出哪里不对吗?
Can you guys see anything incorrect?
是的,您的公式应该改为:
z * height * width + y * width + x
或更高效的形式:
( z * height + y ) * width + x
并且你应该在 x
内部进行循环,否则你将迭代 CPU 缓存。
要明确:在 x
内部进行循环不会影响程序的正确性,它会使程序更高效(包括二维数组上的迭代)。您的程序崩溃是因为您使用错误的公式计算 3d 数组的线性索引。