指向 2D 向量的 C++ 双指针给出了超出范围的错误

C++ double pointer to 2D vector gives out-of-range error

如果这个问题已经得到解答,我深表歉意,但我已经阅读了大量相关内容(我已经被困在这里好几天了),但我似乎找不到任何有用的东西。

我正在尝试使用双指针访问二维向量,该向量是我创建的 class 的数据成员。由于我继承了一个大型程序的现有结构,我必须为此使用指针。不管怎样,vector 在对象被实例化时被初始化,像这样:

CalcData::CalcData(int rows, int cols) : numRows(rows), numCols(cols), dims(2),
          data2D( vector<vector<MKL_Complex16>>( rows, vector<MKL_Complex16>(cols) ) )

(是的,我知道我可以使用模板来避免必须一遍又一遍地使用类型 MKL_Complex16,但我是 C++ 的相对菜鸟,我尽量不要让事情过于复杂。) 无论如何,vector 实例化得很好,并且使用另一个成员函数我能够得到一个可以看到 vector 的第一个元素的双指针:

MKL_Complex16** CalcData::Addr2D() {
    MKL_Complex16* helper2D = &data2D.at(0).at(0);
    return &helper2D;
}

回到调用函数,调试时通过双指针可以看到数组的第一个元素。尝试访问第一行之外的元素时出现问题:

CalcData test2(72, 4);              // instantiate 2D vector object
MKL_Complex16** test2Addr = test2.Addr2D();    // get pointer to that vector
test2Addr[1][3].real = 56;          // write to an element

...在调试器中,此向量如预期的那样在实例化对象中显示为 72x4 向量。但是当我尝试使用指针访问它时,出现了分段错误。例如,我 可以 通过使用 test2Addr[0][4] 访问 test2Addr[1][0]。这告诉我,无论出于何种原因,我精心声明的向量向量被编译器视为一维数组。我尝试用重载的 () 运算符解决这个问题,但事实证明这不适用于指针(b/c 我猜是在开玩笑)。

基本上,尝试使用标准索引 [][] 运算符以外的任何东西都会让我的生活变得更加困难。那么,有没有办法强制编译器识别我的二维数组是二维数组呢?也许通过不同的方式实例化它?如果可能的话,我不想使用 push_back()。

I'm trying to use a double pointer to access a 2D vector.

这是你的问题。可视化数据,您会发现问题所在。

This tells me that for whatever reason my nicely-declared vector-of-vectors is being treated by the compiler as a 1D array.

因为,通过使用这个指针,这就是您告诉它的期望。

So, is there a way to force the compiler to recognize that my 2D array is a 2D array?

不,因为它不是。

不幸的是,人们一直在使用和传播误导性术语,这就是这里发生的事情:没有二维矢量这样的东西。

你有一个向量的向量。没有一个向量管理 MKL_Complex16 的二维集合;向量的向量。外部向量中的每个元素都是另一个向量,由指向数据的指针和一些其他内部元素(例如长度)组成。它效率不高,并且与 MKL_Complex16**.

不兼容

更糟糕的是,您的 Addr2D 函数只是 returns 一个指向局部变量(helper2D 对象)的(悬挂)指针。您不能只是继续添加更多 & 直到编译器错误消失,才能完成工作。

我对 2D 数据的建议总是一样的:制作一个 class 来包裹一个简单的 vector<MKL_Complex16>,它包含 N×M 个元素;让它也包装访问(例如 posactual = posx + posy × width), 来模拟你设想的两个维度。那么你的存储实际上只是所有元素的一个巨大的、连续的块——如果你愿意,你仍然可以方便地在二维中索引它。