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