加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 使用reinterpret_cast将std :: vector中的数据重新整形为指

发布时间:2020-12-16 10:44:08 所属栏目:百科 来源:网络整理
导读:我有一个std :: vector double包含M * N值,我想将其重塑为双**,其行为类似于双[N] [M]多维数组. 这些起点和终点可能看起来很奇怪,但遗憾的是它们都是由外部库决定的,所以我无能为力.我问这个问题,看看是否有办法完成这个,而不是简单地手动复制所有数据. 我确
我有一个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 |
  +----+----+----+----+----+----+

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读