施放T 到T *

将类型T的2D数组转换为T*并取消引用元素是否安全?

由于2D数组的存储器布局是线性的,因此基指针应该等于指向第一个元素的指针。 由于它们指向的最终类型也是相同的,因此不应存在任何对齐差异问题。

或者有一些方面会导致未定义的行为?

要明确我的意思是这样的 –

 int arr[10][10]; int p = *((int*) arr); 

另外,同样的问题,如果我访问超出第一个数组的元素,即(int *)arr + 13.它是否属于超出界限的条款? 因为我访问第一个数组的边界之外。

演员本身很好。 可能确实有问题的是使用指向一个子arrays中的元素的指针来访问另一个子元素中的元素:虽然操作明确定义在较低级别(一切都正确对齐,没有填充,类型匹配,… 。),我对C标准的印象是,它的措辞允许边界检查实现符合标准。

然而,注意,线性遍历多维数组仍然是允许的,因为指向经过子arrays的指针(通常不能被解除引用)也恰好是指向下一个子arrays的第一个元素的指针。 这个想法导致指针算术是非关联的:

我的理解是,诸如(int *)arr + 13类的表达式涉及未定义的行为1 ,但如果将其拆分为两个步骤((int *)arr + 10) + 3 ,则可能会定义得很明确。

如果你想在一个步骤中完成它,当然也可以选择放到字节级别,即(int *)((char *)arr + 13 * sizeof (int)) ,这应该是没有问题的与其他指针类型相比,字符指针由最外层的封闭对象限定。

我之前已经讨论过这个问题,但我不记得是否有一个明确的结论可以解决这个特殊的模糊性。


1 C11,第6.5.6节§8

[…]如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出; 否则,行为未定义。 […]