Blog
网站首页
C结构体内存布局的一些要求推论
C结构体内存布局的一些要求推论
2024-05-16 15:06
2024-05-16 15:14
作者:
xmh0511
提交
##### 1. 类型的大小必须是其对齐要求的整数倍 假设类型`T`的alignment是A, 其大小是Size,因为C中T [N]的数组是连续的N个元素 [dcl.array] p6, [expr.sizeof] p2 > An object of type “array of N U” consists of a contiguously allocated non-empty set of N subobjects of type U, known as the elements of the array, and numbered 0 to N-1. > When applied to a class, the result is the number of bytes in an object of that class including any padding required for placing objects of that type in an array. 因此,两个相邻的元素的地址差值就是Size, 假设前一个元素的地址满足`T`的对齐要求,则其地址为: $$Addr = A * K $$ , 其中K是整数,那么下一个元素的地址则是 $$ AddrNext = A * K + Size $$ 根据[basic.align] p1 > An alignment is an implementation-defined integer value representing the number of bytes between successive addresses at which a given object can be allocated. 这里就要求这两个地址的差值是对齐要求的整数倍, 那么$$ Size \over A$$ 的结果为整数,那么`Size`就必须满足$$Z*A$$,且Z为正整数 ##### 2. 结构体的对齐要求必须大于等于其成员中最大对齐要求的成员 假设结构体`s`的alignment是`S`, 为简化证明,假设其只有一个成员`m`且其对齐要求为`M`, 并且`s`的地址和成员`m`之间可以通过padding填充使得`m`的地址满足对齐要求(实际上,标准不允许结构体和其首个成员数据之间有填充,因为他们的地址是相同的)。 如果 $$ S < M $$, 且根据[basic.align] p4 > Every alignment value shall be a non-negative integral power of two. 因此可得 $$ {M \over S} = 2^n $$, 其中`n > 0` 可得 $$ M = 2^n \times S $$ 假设`s`分配的地址为`k * S`(K是正整数),基于此地址为了让`m`分配在合适的对齐要求的地址上,那么可以求`Padding`, 首先 $${ {K \times S} \over M } = { {K \times S} \over {2^n \times S}} $$ 得 $$ K \times 2^{-n} $$, 此结果为正整数则需要配上 $$ {-k} \times ( 2^{-n} - Z) $$ 其中`K*Z`为正整数,可得出 $$ Pad ={ {-k} \times ( 2^{-n} - Z) \times 2^n \times S } = {K \times S \times (Z \times 2^n -1)} $$ 那么以`K*S`表示的地址为基础,那么下一个元素中成员`m`的地址为 $$ NextMaddr = K \times S + Pad + M + Pad $$ 前一个元素中的`m`与下一个元素中`m`的差值为 $$Dif = M + Pad$$ 除以`M`为整数才能满足下一个元素`m`的对齐要求,结果为 $$ 1 + K \times Z - K \times 2^{-n} $$ 所以仅当 $$ K \times 2^{-n} $$ 整体才是整数。所以`K`不能取任意整数,使的这样的数组成立 反过来,如果`S > M`, 则有 $$ M = S \times 2^{-n} $$ 那么 $$ {{K \times S} \over {S \times 2^{-n}}} = K \times 2^N $$ 任意K都能成立