当我的数据结构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的一部分时,有什么想法我的示例不起作用吗?
谢谢!
答案 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)
除了已经提到的问题,您的代码也违反了严格的别名规则,因此其行为未定义。