C ++以正确的方式在堆上声明静态连续多维数组

问题描述 投票:2回答:1

声明在堆上运行时不会改变大小的多维数组的正确方法是什么? (理想情况下,在C ++ 11中,如果仅在C ++ 14中提供某些功能(而不是C ++ 17),我也很想听听,但是有可能对我不起作用)

到目前为止,我已经浏览了有关该主题的数十个问题和答案,但似乎没有一个真正答案/某些答案与他人冲突。

[我发现的以下解决方案以及它们似乎存在的问题使它们不可行(大多数解决方案来自SO答案及其注释,所有示例均以3D数组为目标给出:]

  • Normal [] [] []数组用新的/声明的指针数组声明问题:在内存中不连续,每个单独的数组在内存中都有其独立的位置

  • 多个std :: arrays / boost :: array相互嵌套问题:在内存中不连续,每个单独的数组在内存中都有其独立的位置

  • 矩阵问题:只是std :: array的容器,基本上存在相同的问题

  • 多个std:vector相互嵌套问题:动态的,几乎前面提到的所有其他问题

  • 声明为单个块,并带有指向普通[]数组的指针,然后在运行时使用类似GetIndex(array,x,y,z)的函数通过计算来遍历索引问题:这似乎可以解决所有问题,但是此解决方案似乎不太理想,因为在您需要经常访问/更改元素时似乎会引入大量的CPU开销

与此无关,如果它们在类中,这些解决方案也有一些问题,我必须使用来从外部访问它们的值。运算符,所以如果有人能以一个正确的声明和对作为类成员的堆分配多维数组的正确访问的例子来说明正确的解决方案,我将不胜感激。

c++ arrays multidimensional-array heap heap-memory
1个回答
0
投票

如果除第一个维外的所有维都是编译时常量(无论第一个维是否为常量),只需编写new T[x][Y][Z]。结果是连续的,如果合适的话,编译器将有机会应用诸如移位之类的技巧而不是乘法。您无法使用这样的实体将其作为指针和大小传递给需要一维数组的函数:

f(&a3[0][0][0],x*Y*Z);  // undefined behavior

因为仅在一个T[]数组(此处为a3[0][0]的数组T[Z])中定义了指针算术。

如果第一维也恒定,则可以使用嵌套的std::array(实际上没有额外的内存开销),或者仅使用

struct A3 {
  T a[X][Y][Z];
};

两者都具有可以由value传递和返回并用作标准容器元素的优点。

© www.soinside.com 2019 - 2024. All rights reserved.