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

时间:2018-02-11 22:36:30

标签: c++ pointers vector outofrangeexception

道歉,如果这已经得到了解答,但我已经对此进行了相当广泛的阅读(我已经被困在这里好几天了)而且我似乎找不到任何有用的东西。

我正在尝试使用双指针来访问2D向量,该向量是我创建的类的数据成员。我必须使用指针,因为我继承了一个较大程序的现有结构。无论如何,在实例化对象时初始化向量,如下所示:

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 ++中是一个相对的noob,我试图不要过于复杂化。) 无论如何,向量实例化得很好,并使用另一个成员函数,我能够得到一个双指针,看到向量的第一个元素:

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笑话,我猜)。

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

1 个答案:

答案 0 :(得分:1)

  

我正在尝试使用双指针来访问2D矢量。

有你的问题。可视化数据,你会发现错误。

  

这告诉我,无论出于什么原因,编译器都将我很好地声明的向量矢量视为一维数组。

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

  

那么,有没有办法强制编译器识别我的2D数组是2D数组?

不,因为它不是。

不幸的是,人们继续使用和传播误导性的术语,这就是这里发生的事情:没有2D矢量这样的东西。

你有一个向量的向量。没有一个矢量管理MKL_Complex16的2D集合;矢量矢量。外部向量中的每个元素都是另一个向量,由指向数据的指针和一些其他内部结构(例如长度)组成。效率不高,与MKL_Complex16**不兼容。

更糟糕的是,您的Addr2D函数只返回指向局部变量(helper2D对象)的(悬空)指针。在编译器错误消失之前,您不能继续添加更多&,以完成工作。

我对2D数据的建议总是一样的:创建一个包含 N×M 元素的简单vector<MKL_Complex16>的类;它也包装访问(例如 pos actual = pos x + pos y ×width ),以模拟您设想的两个维度。那么你的存储实际上只是所有元素的一个巨大的,连续的块 - 如果你愿意,你仍然可以方便地将它编入二维索引。