【问题标题】:Dynamically allocate buffer space for a two-dimensional array -- why does this fail?为二维数组动态分配缓冲区空间——为什么会失败?
【发布时间】:2014-04-12 21:35:02
【问题描述】:

我身处 C++ 多维数组指针地狱之中。我有一个函数,它接受两个指向两个多维数组的指针。该函数将输入数组转换为输出数组。

void transpose(float * in, float * out) throw() {
  size_t numvars = dataset.getVariables().size()
  size_t numsegs = dataset.getSegments().size();
  ...

我在为输出数组动态分配缓冲区时遇到问题。我认为以下方法会起作用,因为数组会自动衰减为指针:

size_t numvars = dataset.getVariables().size()
size_t numsegs = dataset.getSegments().size();
float tData[numvars][numsegs];
transpose(data, tData);

但我得到了错误:

从 'float [(((sizetype)(((ssizetype)numvars) + -1)) + 1)][(((sizetype)(((ssizetype)numsegs) + -1 )) + 1)]' 到 'float*'

那么为什么会失败呢?为二维数组动态分配大小以便transpose 函数可以完成其工作的正确/最佳方法是什么?

【问题讨论】:

  • 不要使用指针。使用正确的数据结构并通过 (const) 引用传递它们。
  • tData 不是浮点数* 是吗?因此出现错误消息。与您所说的相反,转置不采用指向两个多维数组的指针。
  • 我认为这是因为数组衰减为指针。这仅适用于单维数组而不适用于多维数组吗?
  • 一个 n 维数组衰减为指向 (n-1) 维数组的指针。它只会“忘记”它的第一个维度。
  • @Brian Bi - 对于具有固定维度的数组来说确实如此。 float tData[numvars][numsegs] 是一个编译器扩展,我看不到 tData 会衰减到什么数据类型。 int (*)[numsegs] 不是类型。

标签: c++ arrays pointers types multidimensional-array


【解决方案1】:
void transpose(float * in, float * out)
...
float tData[numvars][numsegs];
transpose(data, tData);

tDatafloat[numvars][numsegs] 类型,只能衰减到 float (*)[numsegs]
如果out 期望这个二维数组中第一个元素的地址,那么你可以简单地这样做:

transpose(data, &tData[0][0]);

即:

void foo(float* pF){}

int main()
{
    float f, arr[10], arr2d[5][7];

    foo(&f);            // perfectly straightforward
    foo(arr);           // float[10] decays to float*
    foo(arr2d[0]);      // float[7] decays to float*

    foo(&arr2d[0][0]);  // perfectly straightforward
    foo(arr2d);         // float[5][7] decays to float (*) [7] ~> float* ???
                        // ERROR: can't convert decayed float (*) [7] to float *
}

还要注意float tData[numvars][numsegs]; 不会“动态分配”数组。它是一个具有自动存储持续时间的可变长度数组(又名 VLA)。


但是,您可以考虑使用std::vector,而不是基于指针的 C 风格方法:

typedef std::vector<std::vector<float> > FloatMatrix;

void transpose(const FloatMatrix& in, FloatMatrix& out);
...
FloatMatrix data;
...
FloatMatrix fm = FloatMatrix(numvars, std::vector<float>(numsegs));
transpose(data, fm);

【讨论】:

  • 转置函数知道 tData 应该是的大小。我在编辑中添加了代码以向您展示。是的,转置并不是一个真正安全的功能。我明白了。不过,仍在寻找我的问题的答案。
  • @jakeliquorblues:很公平。我已经编辑了我的答案。
  • 所以 data[numvars] 隐式转换为char *(或&amp;data[0])但data[numvars][numsegs] 没有隐式转换为任何东西?
  • "它是一个具有自动存储持续时间的可变长度数组 (a.k.a. VLA)。" - C++ 没有 VLA,它们是 C99 的东西。 OP 必须使用编译器扩展(因此,涉及此数组的任何行为也是编译器扩展的一部分)。 AFAIK,在 C99 中 tData 不会衰减,而 tData[x] 会衰减到 float *
  • @MattMcNabb:我没有写到 VLA 是标准 C++ 的一部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-06
  • 1970-01-01
  • 1970-01-01
  • 2020-03-13
  • 2014-07-16
  • 2012-05-09
相关资源
最近更新 更多