说我有以下结构:
struct StructA
{
int some_member;
double some_other_member;
};
struct StructB
{
char a_char;
char another_char;
};
Run Code Online (Sandbox Code Playgroud)
现在说我在内存中有一些包含这些结构的缓冲区,我想解析它.缓冲区中的每个结构前面都有一个int描述结构类型的结构.像这样:
struct Descriptor
{
int type;
union
{
struct StructA a;
struct StructB b;
} data;
};
Run Code Online (Sandbox Code Playgroud)
我想做的是将指针转换为buffer(char *)struct Descriptor *,读取类型,然后访问union的正确成员,然后按类型成员的大小+正确联合的大小推进指针成员(例如sizeof(int) + sizeof(struct StructA)).
但是,这是有效的C代码吗?(从某种意义上说,它不会调用未定义的行为.)我主要担心的是内存缓冲区可能小于sizeof(struct Descriptor)因为它只包含StructB前面的类型字段.
即使我只访问内存的有效部分,当底层内存不足以容纳整个结构时,利用指向结构的指针是否合法?编辑:如果它对结构无效,它对联盟有效吗?
我认为只要您正确取消引用指针,即不要触摸超出缓冲区大小的数据,我认为您事先知道并正确处理对齐,它就是有效的。因此,您只需要担心如何正确处理内存缓冲区,除此之外,这是标准对此类转换的规定
\n\n\n6.3.2.3 指针
\n\n
\n- 指向对象类型的指针可以转换为指向不同对象类型的指针。如果生成的指针未针对引用类型正确对齐68),则行为未定义。否则,当再次转换回来时,结果应等于原始指针。当指向对象的指针转换为指向字符类型的指针时,结果指向该对象的最低寻址字节。结果的连续增量,直到对象的大小,产生指向对象的剩余字节的指针。
\n
\n68)一般来说,概念\xe2\x80\x98\xe2\x80\x98正确对齐\xe2\x80\x99\xe2\x80\x99是传递性的:如果指向类型A的指针对于指向类型B的指针正确对齐,进而正确对齐指向类型 C 的指针,然后将指向类型 A 的指针正确对齐为指向类型 C 的指针。
\n
然后,这就是关于作业的内容
\n\n\n6.5.16.1 简单赋值
\n语义学
\n\n
\n- 如果存储在一个对象中的值是从与第一个对象的存储以任何方式重叠的另一个对象读取的,则重叠应是精确的,并且两个对象应具有兼容类型的合格或不合格版本;否则,行为是未定义的。
\n
因此,如果重叠是精确的,那么就可以了,并且行为也已定义。
\n