是否保证C中的数组元素将连续存储,没有填充?

gaa*_*kam 3 c arrays padding memory-alignment pointer-arithmetic

换句话说:如果我有这样分配的数组,它是否可以保证:

void *arr = calloc(nmemb, sizeof(some_type))
Run Code Online (Sandbox Code Playgroud)

然后elta,eltb,eltc将所有指向在存储器中的相同位置,这将是类型的第二个元素some_type此数组的?

some_type *elta = &((some_type*)arr)[1];
some_type *eltb = ((some_type*)arr)+1;
some_type *eltc = (char*)arr+sizeof(some_type);
Run Code Online (Sandbox Code Playgroud)

我问这个的原因是因为我试图在C中做一个"容器",如果这不成立,那么我就没有想法如何返回指向除第一个之外的任何其他元素的指针.

Aco*_*gua 7

是的,它是有保证的.如果添加了填充字节,则将它们添加 struct some_type两个数组元素中,但不在两个数组元素之间.

E. g.:

struct S
{
    int n;
    short s;

// this is just for illustration WHERE byte padding (typically) would occur!!!
#if BYTE_ALIGNMENT >= 4
    unsigned char : 0;
    unsigned char : 0;
#endif
};
struct S s[2];
size_t d = (char*)(s + 1) - (char*)s;
Run Code Online (Sandbox Code Playgroud)

将字节对齐调整为4或8(或更大的2的幂),此结构的大小为8,d将为8,字节对齐设置为1或2,结构的大小为6是......

注:这是不是可能发生的填充字节的唯一的地方:如果您切换成员ns之间,将需要填充字节s,并n得到n正确对齐.另一方面,在n之后不再需要填充字节,因为结构大小将确保已经正确对齐.

参考标准:C11,6.2.5.20:

数组类型描述了具有特定成员对象类型的连续分配的非空对象集,称为元素类型.36)数组类型的特征在于它们的元素类型和数组中元素的数量.[...]

(突出显示我!).