首页 > 解决方案 > 指向数组和有效类型的指针

问题描述

在 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 ]

上面的代码会调用未定义的行为吗?

我在网上搜索,发现大多数关于聚合类型和有效类型的讨论都涉及结构指针,而不是指向数组的指针。即便如此,对于设置单个结构成员是否仅对该成员或该结构将包含的整个内存块赋予有效类型似乎存在分歧和混淆。

标签: cpointerslanguage-lawyerpointer-to-array

解决方案


//Is the effective type of the memory for (*foo)[ 0 – 9 ] now also int?

如果您要问整个区域的有效类型是否为 (one) int,那么我认为很难对此进行论证。我倾向于说不,但正如 Eric 在评论中所说,这里的语言规范并不清楚。

如果您要问的有效类型是否*foo是 now int[10],那么有一个更简单的论点。我倾向于说“是”。如果该位置被接受,则对于每个具有有效类型int尾部的九个大小的子区域有更强有力的论据,但这并不是一个无懈可击的位置。*fooint

//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则行为未定义。其他动作组合的定义可能不太明确。


推荐阅读