使用二维数组作为一维数组是否正确?可能会导致未定义的行为吗?

时间:2018-01-05 23:27:07

标签: c++ arrays

这段代码是否合适?出于某种原因使用2维数组作为1维弃用了吗?

char tab1[3][3];

for(int i = 0; i < 3; i++)
    for(int j = 0; j < 3; j++)
       tab1[i][j] = (char)i;

printf("%c", ((char*)tab1)[3]); // == tab1[1][0]

2 个答案:

答案 0 :(得分:0)

  

出于某种原因,是否将二维数组用作1维?

当你使用tab1的方式时,它会衰减到类型为char (*)[3]的指针(指向3 char s的数组的指针)。它不会衰减到char*

如果没有明确地投射它,就不能将它用作char*

  

回复:这段代码是否合适?

很明确,因为对于代码中的tab1&tab1&tab1[0]&tab1[0][0]指向内存中的相同位置,即使它们都是不同的类型

答案 1 :(得分:0)

如果没有其他原因,这很好,因为char可以根据标准对所有其他类型进行别名。此外,多维数组被分配为一个连续的块,因此它是内存中的一维数组。

我们知道tab1衰减到指向连续多维数组(这是一个数组)的第一个元素的指针,并将数组指针强制转换为char*(哪个可以别名)必须没问题。

如果有疑问,你可以随时&tab1[0][0]。再次,因为我们知道分配的内存是连续的。

修改

如果这是一个整数数组(int tab1[3][3]),那么故事就会有所不同。根据我的理解 C++17之前的标准,标准表示指向正确对象类型的指针有效无论如何获得其值。这意味着转换为int*应该没问题,因为我们知道tab1产生的地址与第一个元素的地址相同。

然而 C++17后保证已被删除,因此此广播可能未定义的行为

See THIS question了解详情。

出于这个原因,我总是建议使用始终有效的&tab1[0][0]