2017-10-28 68 views
0

说你有这样定义维度x每Y(每Z)的矩阵:指针2或3维子阵列/子矩阵

int** tab = new int*[x]; 
for(int i=0; i<x; ++i) tab[i] = new int[y]; 

int*** tab = new int**[x]; 
for(int i=0; i<x; ++i) { 
    tab[i] = new int*[y]; 
    for(int j=0; j<y; ++y) tab[i][j] = new int[z]; 
} 

是有任何智能的方法来访问子矩阵(得到int**(*)没有数据复制,普通的C++),它将具有左上(前)角[a,b(,c)]和[A,B(,C)]的大小] ?

下面是(更好或更差)问题的图形示例。

matrix 2d example enter image description here

+0

访问子数组只能以非常有限的方式工作。看看[SO:二维数组如何存储在内存中?](https://stackoverflow.com/q/38204677/7478597)了解原因。 – Scheff

+0

顺便说一句。你可以用int(* pA3d)[3] [4] [5] = new int [3] [4] [5];来分配一个3d数组;但是这仅限于具有固定大小的多暗数组。对于不同的尺寸,_I_会降低多点模糊。麻烦和1昏暗的工作。阵列。如果你真的想要这个多昏暗的东西'std :: vector'可以使你的生活更轻松(例如'std :: vector >>'但是又一次:我宁愿'std: :vector '并且自己做多偏暗索引,你可以把它作为Eigen lib包装在一个专用的'class MyMatrix'中。) – Scheff

+0

嗯。更好地忘记'int(* pA3d)[3] [4] [5] = new int [3] [4] [5];'。我真的不确定指向数组的指针与指向第一个元素的指针。 (虽然我记得自己有一天在好奇心的尝试中掌握了它,但这种哭声不绝于耳。) – Scheff

回答

2

您正在使用所谓的锯齿状排列。它是一个数组数组,除了运行时之外,没有其他的东西强制子数组的大小相同。因此锯齿状,因为你可能有不同的大小的子阵列。

为了让子矩阵也是锯齿阵列,您需要在那里存在指向子矩阵的子阵列的指针锯齿阵列。这些通常不存在,所以不,你不能“不复制”至少一些指向子数组的指针数组。

如果你的矩阵不是基于锯齿的数组,而是单个数组与stride,那么可以在不分配新的子数组指针数组的情况下创建子数组的视图。它也会更加缓存友好。

要编写非锯齿矩阵,首先编写处理一维的数组视图或span类。

对于两个维度,您需要扩展span类以存储维度大小或步幅的元组。 []而不是返回对计算元素的引用,创建一个指向计算位置的一维下跨度实例,直到返回引用的维度为0的情况。

这将是高效的,允许高效的子阵列,但需要几十或100行代码才能正确使用。

+0

“大步”是我的下一个想法,但是我的答案出现在我写下来之前。因此,我至少确定了一些错别字,并添加了一个链接,因为跨步可能不是那么常见(如果你不知道它的用途)。 – Scheff