C语言数组是否存在尾部填充?sizeof计算的标准合规性验证
关于C语言数组sizeof计算的标准合规性问题
原测验题与核心疑问
给定测验题:
size_t f(int *a[2][3][4]) { return sizeof(*a); }
疑问:答案为sizeof(int *) * 3 * 4是否正确?换而言之,ISO C标准是否保证以下等式必然成立?
sizeof(int *) * 3 * 4 == sizeof(int*[3][4])
核心关注点:数组是否可能存在尾部填充字节,从而打破上述等式?
关于参数类型的补充说明
有人疑惑参数声明中的[2]去向——根据ISO C11标准第6.7.6.3条第7款:当函数参数被声明为数组类型时,会被自动调整为指向该数组首元素的指针类型。因此,原参数int *a[2][3][4]的实际类型是int *(*a)[3][4],对a解引用后得到的是int*[3][4]类型的二维数组。
核心问题解答
结论:ISO C标准严格保证该等式成立,数组不存在尾部填充字节。
具体依据:
- C标准明确规定,数组的总大小等于「单个元素的大小 × 元素个数」,不存在任何额外的尾部填充。对于多维数组而言,它本质是“数组的数组”,每一层数组都遵循这一规则:
int*[3][4]是包含3个元素的数组,每个元素是int*[4]类型的一维数组;int*[4]的大小为sizeof(int*) * 4,因此外层数组的总大小就是3 × sizeof(int*[4]) = 3 × 4 × sizeof(int*),与sizeof(int*) * 3 *4完全相等。
- 标准同时规定,数组元素之间不存在填充(除非元素类型自身因对齐要求存在内部填充,但这属于元素大小的一部分,并非数组额外添加的)。此外,数组尾部不会有填充——因为指针算术的行为是标准严格定义的,若数组存在尾部填充,会导致下标访问、指针偏移等操作的地址计算出错,违背标准对指针算术的约束。
内容的提问来源于stack exchange,提问作者Damian Rhodes
相关产品推荐
相关产品推荐

