结构传递给函数后大小不同

Struct has different size after being passed to func

本文关键字:函数 结构      更新时间:2023-10-16

我创建了一个带有Id变量和值列表的结构。当我在将其作为void*传递给函数之前检查大小时,它是12。一旦进入函数,它就是4。我怎样才能保持尺寸不变?

结构代码:

typedef struct
{
    int id;
    std::list<int> sensorValues;
}dataPacketDef;

发送给其他功能码:

  void SendDataBufferToServer()
{
    cout << "Sending network data size: " << sizeof(dpd) << "n";
    client.writeData((void*)&dpd);
}

在上面的函数中,size是12,而在接收函数中,size只有4。该结构体声明为主程序的全局变量。

在函数中,您取的是void*的大小,而不是dataPacketDef的大小。显然,在您的系统上,sizeof(void*)是4字节。sizeof操作符仅仅是类型驱动的:它不会对点进行神奇的检查。实际上,由于您已经使用过时的强制转换执行了类型擦除,因此不能

不能以这种方式序列化对象。这个列表不是扁平的数据;它的元素实际上不是dataPacketDef的一部分,而是动态分配的。列表保存着指向这些元素的指针。你所做的只是序列化指针,这些指针在目标系统上立即变得没有意义。

完全放弃这种方法,并研究如何在现代c++中正确地序列化对象。

在作为void类型传递给函数之前,它是12。一旦进入函数,它就是4

因为sizeof指针在你的程序的情况下是4个字节,你不能读取sizeof结构如果你将你的结构的实例强制转换为void*。你可以通过传递给你的函数也你的结构体的大小foo(static_cast<void*>(&myStructObj), sizeof(TypeOfMyStruct))来修复它。

[编辑]

也正如Lightness Races in Orbit在他的回答中指出的,序列化std::list是错误的,你只会写指针到你的文件/

指针的大小为4字节(如果使用x64编译器则为8字节)。如果writeData需要知道指向对象的大小,则需要将该信息以某种方式传递给它;一个常见的习惯用法是将大小作为第二个参数传递。完成这些后,您可以使用辅助函数模板来简化:

template<typename T>
void writeData(Client& client, const T& obj)
{
   client.writeData((void*)&obj, sizeof(obj));
}

尽管molbdnilo在问题评论中指出,由于dataPacketDef中存在list, client.writeData()可能仍然无法做你想做的事情。

正确。

指针总是包含一个地址,在你的机器上是4个字节。

因此,在32位寻址架构下,任何指针的大小都是4字节。

sizeof(void*)在32位机器上是4字节