Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;在不复制c数组的情况下分配N维向量_C++_Arrays_Vector_C++11 - Fatal编程技术网

C++ C++;在不复制c数组的情况下分配N维向量

C++ C++;在不复制c数组的情况下分配N维向量,c++,arrays,vector,c++11,C++,Arrays,Vector,C++11,我想将N维矩阵从磁盘(HDF5)加载到std::vector对象中 我事先知道他们的级别,只是不知道他们的形状。例如,其中一个矩阵是4秩std::向量数据 我想使用向量来存储值,因为它们是标准的,不像c数组那样难看(主要是因为它们知道它们的长度) 但是,加载它们的方法是使用一个加载函数,该函数接受一个void*,这对于秩1向量很好,我可以调整它们的大小,然后访问它的数据指针(vector.data())。对于更高的秩,vector.data()将只指向vectors,而不是实际的数据 最糟糕的情

我想将N维矩阵从磁盘(HDF5)加载到
std::vector
对象中

我事先知道他们的级别,只是不知道他们的形状。例如,其中一个矩阵是4秩
std::向量数据

我想使用向量来存储值,因为它们是标准的,不像c数组那样难看(主要是因为它们知道它们的长度)

但是,加载它们的方法是使用一个加载函数,该函数接受一个
void*
,这对于秩1向量很好,我可以调整它们的大小,然后访问它的数据指针(
vector.data()
)。对于更高的秩,
vector.data()
将只指向
vector
s,而不是实际的数据

最糟糕的情况是,我只是将所有数据加载到一个辅助c数组,然后手动复制,但对于大型矩阵,这可能会大大降低速度


有没有一种方法可以将连续的多维数据放在向量中,然后获得一个地址?

如果您担心性能,请不要使用向量向量的向量

这就是原因。我认为这个问题的答案值得一读

它既胖又慢的原因其实是一样的。矩阵中的每个“行”都是一个单独分配的动态数组。进行堆分配在时间和空间上都很昂贵。分配器需要时间进行分配,有时运行O(n)算法来完成分配。分配器用额外的字节“填充”每个行数组,以便记账和对齐。额外的空间需要…嗯…额外的空间。当您去取消分配矩阵时,deallocator也会花费额外的时间,费力地释放每个单独的行分配。一想到它就让我汗流浃背

这还有另一个原因。这些独立的分配往往存在于内存的不连续部分。一行可能在地址1000处,另一行在地址100000处,你明白了。这意味着当你遍历矩阵时,你就像一个狂人一样在记忆中跳跃。这往往会导致缓存未命中,从而大大降低处理时间

因此,如果您必须使用可爱的[x][y]索引语法,请使用该解决方案。如果你想要敏捷和小(如果你不关心那些,为什么你在C++中工作),你需要一个不同的解决方案。
对于二维矩阵,可以使用丑陋的c数组,如下所示:

float data[w * h]; //width, height
data[(y * w) + x] = 0; //access (x,y) element
对于三维矩阵:

float data[w * h * d]; //width, height, depth
data[((z * h) + y) * w + x] = 0; //access (x,y,z) element
等等。要从文件加载数据

float *data = yourProcToLoadData(); //works for any dimension

这不是很容易扩展,但是您需要处理一个已知的维度。这样,您的数据是连续的,只有一个地址。

您的计划并不明智。向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量向量

而不是您的计划,加载到flst向量中

接下来,用多维视图包装它

template<class T, size_t Dim>
struct dimensional{
  size_t const* strides;
  T* data;
  dimensional<T, Dim-1> operator[](size_t i)const{
     return {strides+1, data+i* *strides};
  }
};
template<class T>
struct dimensional<T,0>{
  size_t const* strides; // not valid to dereference
  T* data;
  T& operator[](size_t i)const{
     return data[i];
  }
};
模板
结构维度{
尺寸常数*跨步;
T*数据;
维数运算符[](大小)常数{
返回{strips+1,data+i**strips};
}
};
模板
结构维度{
size\u t const*strips;//对取消引用无效
T*数据;
运算符[](大小)常量(&T){
返回数据[i];
}
};
其中,
步长
指向每个维度的数组步长数组(所有后续维度大小的乘积)

因此,
my_data.access()[3][5][2]
获取特定元素

这个解决方案的草图将所有内容都公开,不支持(:)
迭代。一个更具运输质量的系统将具有适当的隐私和循环支持风格


我不知道已经为您编写的高质量多维阵列视图的名称,但在boost中几乎肯定有一个。

听起来您可以使用更好的库来实现您的目的,我建议将矩阵存储在一个平面
std::vector
中,并将其封装在一个类中,以假装它有多个维度。这使您可以调用向量上的
data
,以获取指向矩阵(连续)的整个数据的指针。否则,您基本上有一个
浮点****
,其中每个
*
可以位于内存中的任何位置(不连续)。