C中更大或更小的结构

时间:2009-12-28 04:17:58

标签: c structure casting

我在C程序中有两个结构: SmallStructABC和BigStructXYZ

我在他们两个人中都有几个成员; SmallStructABC的所有10个成员与BigStructXYZ的前10个成员完全相同。 BigStructXYZ还有50名成员。

将这两个结构相互转换为可以吗?

SmallStructABC *i = (BigStructXYZ*)j;
BigStructXYZ   *a = (SmallStructABC*)b; 

我只能在打字后访问前10个(普通)成员。

我写了C程序,它在我的机器上工作正常。只是想验证我是否需要处理任何极端情况(对齐,无效读取,非gcc编译等)..

编辑: 问:为什么我想做这样的事情?

答:BigStructXYZ的大小非常大(比如说50KB)并且包含一些标题(键,地图等)。 我在通过网络发送之前压缩这些数据。我保留标题(在我们的例子中是SmallStructABC)。 通过类型转换,我可以在需要时从头文件中访问这些键。

4 个答案:

答案 0 :(得分:10)

不,这不是个好主意。更好的方法是将结构指针输入结构并通过指针操作它们:

void DoSomething(Small *thing) {
    // ...
}

int main() {
    Big big = {0};
    Small small = {0};

    Small *p0 = (Small*)&big;
    Small *p1 = &small;

    DoSomething(p0);
    DoSomething(p1);

    return 0;
}

另一种更安全的设计是根据Big定义Small

typedef struct Small {
    int foo;
};
typedef struct Big {
    Small small;
    int y;
};

答案 1 :(得分:3)

上面的代码无法编译。 j已经是BigStructXYZ,你的意思是将其转换为SmallStructABC吗?

无论如何,你要做的是一个坏主意。将SmallStructXYZ作为BigStructXYZ中的第一个字段并更好地工作会更好:

SmallStructABC i = j.smallStruct;
BigStructXYZ a = { b };

答案 2 :(得分:1)

我可以想到这样的情况不能保证在我的头脑中起作用,但在大多数情况下大多数平台应该没问题。我想到的一点是,对齐应该由结构的最大成员决定,所以如果在更大的结构中有64位成员或其他东西,它可能会影响对齐前几个成员。对不起,我现在没有更坚实的消息来源或更明确的解释。

在我自己的代码中,我更喜欢将标题直接嵌入到更大的结构中,如Frank Kreuger的答案所述,并使用bigStruct.header.someMember类型的接口来避免任何和所有的转换和对齐困难。

答案 3 :(得分:0)

是的,你可以做到。 SmallStructABC将在内存中与BigStructXYZ的第一部分完全相同。

我和工会一起使用了这个。系统接收有效负载,可能是标头或标头+数据。

我写了这样的联盟:

union HeaderOrHeaderData
{
    SmallStructABC header;
    BigStructXYZ headerData;
};

HeaderOrHeaderData* ptr = (HeaderOrHeaderData*) data_ptr;

这种方法优于直接转换的优点是可能 - 错误 - bug结构的指针(实际上指向小结构)并使用它,因为它指向大结构。

如果你总是使用工会,你会三思而行。

我尝试了几个编译器,操作系统和平台的解决方案。它在任何时候都可以正常工作。