在C中指针指向数组的情况下,我对有效类型感到困惑。通过指向数组的指针访问单个成员是否只在该成员的内存上或在数组包含的所有内存中赋予有效类型?《标准》在这方面是否明确?
int ( *foo )[ 10 ] = malloc( sizeof( *foo ) );
**foo = 123; //Or ( *foo )[ 0 ] = 123
//Is the effective type of the memory for (*foo)[ 0 – 9 ] now also int?
//Does the whole region now have an effective type?
//Or can this memory be used for other purposes?
这里有一个实际的例子:
int (*foo)[ 10 ];
double *bar;
//Figure out the size an int padded to comply with double alignment
size_t padded_int_size =
( ( ( sizeof( int ) + alignof( double ) - 1 ) / alignof( double ) ) * alignof( double ) );
//Allocate memory for one padded int and 1000 doubles,
//which will in any case be larger than an array of 10 ints
foo = malloc( padded_int_size + sizeof( double ) * 1000 );
//Set our double pointer to point just after the first int
bar = (double*)( (char*)foo + padded_int_size );
//Do things with ( *foo )[ 0 ] or **foo
//Do things with bar[ 0 - 999 ]
上面的代码是否调用了未定义的行为?
我在网上搜索发现,大多数关于聚合类型和有效类型的讨论都涉及结构指针,而不是指向数组的指针。即便如此,对于设置单个结构成员是否只为该成员或该结构将包含的整个内存块赋予有效类型,似乎仍存在分歧和困惑。
//Is the effective type of the memory for (*foo)[ 0 – 9 ] now also int?
如果你问整个区域的有效类型是否是(一个(int
,那么我认为很难对此进行论证。我倾向于说不,但正如Eric在评论中所说,这里的语言规范并不明确。
如果你问*foo
的有效类型现在是否是int[10]
,那么有一个更容易的论点。我倾向于说";是的";。在接受该位置的情况下,对于*foo
尾部的九个int
大小的子区域,每个子区域都具有有效类型int
,有更有力的论据,但这不是一个无懈可击的位置。
//Does the whole region now have an effective type?
请参阅上文。
//Or can this memory be used for other purposes?
这不是唯一的选择。任何或所有分配的对象都可以用于其他目的,而与前面问题的答案无关。没有声明类型的对象的有效类型可以通过写入该对象来重新分配。
//Do things with ( *foo )[ 0 ] or **foo //Do things with bar[ 0 - 999 ]
以上代码是否调用未定义的行为?
foo
和bar
的值的计算和分配很好。剩下的至少在一定程度上取决于所做的事情。如果通过foo
写入全部或部分空间,然后通过bar
读取回同一空间,则行为未定义。其他动作组合的定义可能不太明确。