Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.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++ 从std::vector重塑数据<;双倍>;使用reinterpret\u cast转换为指定尺寸的双**_C++_Arrays_C++11_Multidimensional Array_Reinterpret Cast - Fatal编程技术网

C++ 从std::vector重塑数据<;双倍>;使用reinterpret\u cast转换为指定尺寸的双**

C++ 从std::vector重塑数据<;双倍>;使用reinterpret\u cast转换为指定尺寸的双**,c++,arrays,c++11,multidimensional-array,reinterpret-cast,C++,Arrays,C++11,Multidimensional Array,Reinterpret Cast,我有一个包含M*N值的std::vector,我想将其重塑为一个double**,其行为类似于一个double[N][M]多维数组。 这些起点和终点可能看起来很奇怪,但不幸的是它们都是由外部库决定的,所以我对此无能为力。我问这个问题是想看看是否有一种方法可以实现这一点,而不必简单地手动复制所有数据 我确实读过,但它的起点略有不同——它不是从std::vector到double**,而是从double[]到double[][。我试图了解那里发生了什么,并将相同的原则应用到我的案例中,但我无法让我的

我有一个包含
M*N
值的
std::vector
,我想将其重塑为一个
double**
,其行为类似于一个
double[N][M]
多维数组。 这些起点和终点可能看起来很奇怪,但不幸的是它们都是由外部库决定的,所以我对此无能为力。我问这个问题是想看看是否有一种方法可以实现这一点,而不必简单地手动复制所有数据

我确实读过,但它的起点略有不同——它不是从
std::vector
double**
,而是从
double[]
double[][
。我试图了解那里发生了什么,并将相同的原则应用到我的案例中,但我无法让我的代码正常工作。如何正确地执行此操作

const int M = 3;
const int N = 2;
std::vector<double> f = { 0, 1, 2, 3, 4, 5 };

double* f1d = f.data();

// compiles and doesn't crash
// but f2d seems to be unitialized (at least f2d[1][1] is garbage)
// also has the wrong type (double[][] rather than double**)
double (&f2d)[N][M] = reinterpret_cast<double (&)[N][M]>(f1d);

// segfaults when trying to access e.g. f2d[0][0]
double** f2d = reinterpret_cast<double**>(f1d);
预期产出:

0 1 2 
3 4 5

显然,您无法从数组中获取有效的
double**
,因为没有要指向的
double*
数组。您需要将平面数组重新解释为二维数组,而不是指针数组

第一次尝试几乎是正确的;但它将指向指针f1d的引用(而不是指向的数组)重新解释为二维数组。取消对指针的引用,并重新解释对数组的引用,应该可以:

double (&f2d)[N][M] = reinterpret_cast<double (&)[N][M]>(*f1d);
                                                         ^

基于
double**
的“数组”与实际的多维数组完全不同,即
double[N][M]
。它具有完全不同的布局和存储不同的信息,因此如果不存储任何附加信息,您就不可能做您想要做的事情

基于
double**
的“数组”的工作方式是使用两级结构,其中第一级是一个数组,其中包含指向各种常规一维数组的指针。连续的多维数组不能直接作为基于
double**
的“数组”运行,因为带指针的一级结构不见踪影:double[N][M]中的各种子数组都是由基址和大小隐式表示的

double[3][2]
+----+----+----+----+----+----+
| 00 | 01 | 02 | 10 | 11 | 12 |
+----+----+----+----+----+----+

double**
+------------+------------+
| 0xDEADD00D | 0xDEADBABE |
+------------+------------+
      |            |
+-----+            |
|                  |
v                  |
+----+----+----+   |
| 00 | 01 | 02 |   |
+----+----+----+   |
                   v
                   +----+----+----+
                   | 10 | 11 | 12 |
                   +----+----+----+
现在,这已经过时了,我们了解了基于
double**
的“数组”是如何工作的,我们可以开始尝试解决您的问题了

要获得一个
double**
,您需要做的是通过使用指向单个连续数组中各种地址的指针填充一个单独的指针数组来自己提供第一级结构

std::vector<double*> index;
index.reserve(M);
for(int i = 0; i < M; ++i) {
    index.push_back(&f[i*N]);
}
double** f2d = index.data();

double**相当于双[N][M]多维数组
。。。停止不,不是。一点也不。@Tomas,不,不是真的。@TomasLycken:不,他们不能。一个
double**
可以指向一个
double*
s数组,但它不能指向一个
double
s数组,一维、二维或任何维。你好像没在听我说话。哦,好吧,光明想告诉你的是,你认为你拥有的选择不是一种选择。这根本不起作用,谢谢。这看起来值得一试。这两方面都解释了为什么我对我试图做的事情有误解,以及如何解决它。跑得很有魅力!
double[3][2]
+----+----+----+----+----+----+
| 00 | 01 | 02 | 10 | 11 | 12 |
+----+----+----+----+----+----+

double**
+------------+------------+
| 0xDEADD00D | 0xDEADBABE |
+------------+------------+
      |            |
+-----+            |
|                  |
v                  |
+----+----+----+   |
| 00 | 01 | 02 |   |
+----+----+----+   |
                   v
                   +----+----+----+
                   | 10 | 11 | 12 |
                   +----+----+----+
std::vector<double*> index;
index.reserve(M);
for(int i = 0; i < M; ++i) {
    index.push_back(&f[i*N]);
}
double** f2d = index.data();
index
  +------------+------------+
  | 0xDEADD00D | 0xDEADBABE |
  +------------+------------+
        |            |
  +-----+        +---+
  |              |
  v              v
  +----+----+----+----+----+----+
f | 00 | 01 | 02 | 10 | 11 | 12 |
  +----+----+----+----+----+----+