当我的数据结构ssspecificdata包含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;”作为ssspecificdata的一部分,则输出是正确的:
90
80
90
80
如果字段“tm m_Date;”是ssspecificdata的一部分,则输出错误:
90
80
0 <-- !
90 <-- !
如果有tm类型的字段作为ssspecificdata的一部分,是否知道为什么我的示例不起作用?
谢谢!
最佳答案
这与结构包装有关。通过将tm
字段添加到ssspecificdata中,可以将其从一个自然对齐的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和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
关于c - TM结构的奇怪类型转换问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2431692/