tm结构的奇怪铸造问题

时间:2010-03-12 09:39:48

标签: c

当我的数据结构sSpecificData包含tm类型的字段时,我遇到以下转换问题:

typedef struct
{
   unsigned char  data[10000];
} sDataBuffer;

typedef struct
{
   int                 m_Id;
   sDataBuffer         m_Data;
} sData;

typedef struct {
   int                       m_value1;
   int                       m_value2;
   tm                        m_Date;
} sSpecificData;

const int SPECIFIC_SVC_DATA_SIZE = sizeof(sSpecificData);

typedef struct {
   int                    m_Id;
   sSpecificData          m_Data;
} sMyData;

int main(void)
{
       sData svc;
       sMyData* ptr1 = (sMyData*) &svc;
       sSpecificData* ptr2;
       ptr2 = (sSpecificData*) &svc.m_Data;
       ptr1->m_Data.m_value1 = 90;
       ptr1->m_Data.m_value2 = 80;
       cout << ptr1->m_Data.m_value1 << endl;
       cout << ptr1->m_Data.m_value2 << endl;
       cout << ptr2->m_value1 << endl;
       cout << ptr2->m_value2 << endl;       
       return 0;
}

没有字段“tm m_Date;”作为sSpecificData的一部分,输出是正确的:

90
80
90
80

字段“tm m_Date;”作为sSpecificData的一部分,输出是错误的:

90
80
0   <-- !
90  <-- !

当存在类型为tm的字段作为sSpecificData的一部分时,有什么想法我的示例不起作用吗?

谢谢!

3 个答案:

答案 0 :(得分:2)

这与结构包装有关。通过将tm字段添加到sSpecificData,您将其从具有int(4字节)的自然对齐的结构更改为具有看似8字节的自然对齐的结构。

所以tm作为sSpecificData的一部分,结构sMyData实际上就是这个

typedef struct {
   int                    m_Id;
   // 4 bytes of padding inserted to align sSpecificData on an 8 byte boundary.
   sSpecificData          m_Data; // with tm, this has a alignment of 8
} sMyData;

这解释了你所看到的。要解决此问题,您可以向sMyData AND添加显式填充值到sData。

typedef struct
{
   int                 m_Id;
   int                 m_padding;
   sDataBuffer         m_Data; // this accepts structures with an alignment of up to 8 
} sData;

typedef struct {
   int                    m_Id;
   int                    m_padding;
   sSpecificData          m_Data; // with tm, this has a alignment of 8
} sMyData;

或者您可以使用#pragma pack(4)(如果您的c编译器支持它)强制填充不在sMyData中,但这会导致tm未对齐,这不是一个好主意。看到这个相关的问题。

今天提出了一个关于C#的非常类似的问题,但问题是相同的,(指定打包的语法虽然不同) Size of structures in .NET

答案 1 :(得分:1)

通常,这种内存操作非常依赖于平台。

主要问题是,由于数据对齐,内存中的变量可能不在您期望的位置。

答案 2 :(得分:0)

除了已经提到的问题,您的代码也违反了严格的别名规则,因此其行为未定义。