将一维数组重新整形为多维数组

时间:2013-03-07 23:01:38

标签: c++ c++11 multidimensional-array language-lawyer

考虑到整个C ++ 11标准,任何符合要求的实现是否有可能成功完成下面的第一个断言,但后者失败了?

#include <cassert>

int main(int, char**)
{  
    const int I = 5, J = 4, K = 3;
    const int N = I * J * K;

    int arr1d[N] = {0};
    int (&arr3d)[I][J][K] = reinterpret_cast<int (&)[I][J][K]>(arr1d);
    assert(static_cast<void*>(arr1d) ==
           static_cast<void*>(arr3d)); // is this necessary?

    arr3d[3][2][1] = 1;
    assert(arr1d[3 * (J * K) + 2 * K + 1] == 1); // UB?
}

如果不是,这在技术上是不是UB,并且如果第一个断言被删除,那么答案是否会改变(reinterpret_cast是否保证在这里保留地址?)?另外,如果重塑是在相反方向(3d到1d)或从6x35阵列到10x21阵列进行的,那该怎么办?

编辑:如果答案是因为reinterpret_cast这是UB,是否还有一些其他严格遵守的重塑方式(例如,通过static_cast到/来自中间人void *)?

1 个答案:

答案 0 :(得分:1)

我觉得它会起作用。您分配相同的连续内存。我知道C标准至少保证它是连续的。我不知道C ++ 11标准中的内容。

然而,第一个断言应该始终为真。数组的第一个元素的地址将始终相同。由于分配了相同的内存,因此所有内存地址都是相同的。

因此,我也会说第二个断言将永远成立。至少只要元素的排序总是按行主顺序排列。这也得到了C标准的保证,如果C ++ 11标准说的不同,我会感到惊讶。