c – 使用reinterpret_cast将std :: vector中的数据重新整形为指定维度的double **

c – 使用reinterpret_cast将std :: vector中的数据重新整形为指定维度的double **,第1张

概述我有一个std :: vector< double>包含M * N值,我想将其重塑为双**,其行为类似于双[N] [M]多维数组. 这些起点和终点可能看起来很奇怪,但遗憾的是它们都是由外部库决定的,所以我无能为力.我问这个问题,看看是否有办法完成这个,而不是简单地手动复制所有数据. 我确实阅读了this question, with an excellent answer,但起点略有不同 – 而不 我有一个std :: vector< double>包含M * N值,我想将其重塑为双**,其行为类似于双[N] [M]多维数组.
这些起点和终点可能看起来很奇怪,但遗憾的是它们都是由外部库决定的,所以我无能为力.我问这个问题,看看是否有办法完成这个,而不是简单地手动复制所有数据.

我确实阅读了this question,with an excellent answer,但起点略有不同 – 而不是从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);

最后,我需要将我的数据传递给一个带有双**参数的方法,因此以下必须编译并运行没有问题:

#include <iostream>#include <vector>voID test(int M,int N,double **arr) {    for (int i = 0; i < N; ++i) {        for (int j = 0; j < M; ++j) {            std::cout << arr[i][j] << " ";        }        std::cout << std::endl;    }};int main() {    const int M = 3;    const int N = 2;    std::vector<double> f = { 0,5 };    // whatever I need to do here to get f2d    test(M,N,f2d);    return 0;}

预期产量:

0 1 2 3 4 5
解决方法 基于双**的“数组”是与实际多维数组完全不同的野兽,即双[N] [M].它具有完全不同的布局并存储不同的信息,因此您无法在不存储任何其他信息的情况下执行所需 *** 作.

基于双**的“数组”工作的方式是使用两级结构,其中第一级是包含指向各种常规一维数组的指针的数组.连续的多维数组不能直接作为基于双**的“数组”运行,因为带有指针的第一级结构无处可见:double [N] [M]中的各种子数组是从基地址隐含的,尺寸.

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 |  +----+----+----+----+----+----+
总结

以上是内存溢出为你收集整理的c – 使用reinterpret_cast将std :: vector中的数据重新整形指定维度的double **全部内容,希望文章能够帮你解决c – 使用reinterpret_cast将std :: vector中的数据重新整形为指定维度的double **所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1222426.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存