QT中发送结构体占用字节相关问题

前言

最近通过上位机发送数据的时候,针对收到的数据突然多出几个bit产生了疑问。用sizeof来看占据的字节大小,发现和实际应该发送的不对。后面查阅了相关资料,理解了这一部分原因,这里做一个记录。


1. 结构体大小问题

struct EDWINWZY
    {
        uint64_t A=500;
        struct Test {
            uint16_t B;
            uint16_t C;
        } test;
    }edwinwzy;

错误想法:结构体大小8+2+2=12个字节
原因:计算结构体大小时需要考虑其内存布局,结构体在内存中存放是按单元存放的,每个单元多大取决于结构体中最大基本类型的大小。A为uint64_t类型即64bit,占8字节,这个没错。B和C都是uint16_t占2字节,也没错。但是B+C=32bit < 64bit(最大基本类型),所以实际上结构体占用的是两个单元大小,即2*8=16字节。

那么拓展一下,我sizeof(edwinwzy),得到的应该就是16,但是如果我对edwinwzy结构体对象的test进行sizeof呢?得到的是结果是4,这是因为用sizeof的时候,针对的是结构体Test,这个结构体里面的最大基本类型是uint16_t,又因为BC是同类型,他们都占满了结构体Test的单元,所以才为4。


2. 添加位域后的结构体大小

struct EDWINWZY
    {
        uint64_t A=500;
        struct Test{
            uint16_t B:1;
            uint16_t C:1;
            uint16_t D:1;
            uint16_t E:1;
            uint16_t F:1;
        } test;
    }edwinwzy;

错误想法:结构体大小所占bit位:64+1+1+1+1+1=69位,69位就是9个字节。
原因:和问题一相同,也是和结构体的内存布局有关,这个结构体内最大基本类型的大小也是uint64_t,占8字节。
所以这里EDWINWZY结构体的大小其实也是16字节。

那同样的,对Test结构体使用sizeof。
错误想法:因为使用了位域,所以结构体里面只用了5位,应该是占用1字节。
原因:结构体Test内最大基本类型的大小是uint16_t,占2字节。所以结构体内存储单元是2字节。这里虽然使用了位域,只占了5位,但是结构体Test的存储单元的长度是2字节,所以这里sizeof(Test)还是2字节,即uint16_t的长度。


3.发送数据多出几个bit

对于上面问题2,我实际的数据可能只有64+5=69位,但是我结构体大小要占用的是128位(uint64_t*2),后面缺了59位都是用0补全。
因此这里接收到的数据就会多出很多个bit位为0的情况。

总结

这个问题第一次碰到,之前学C语言相关的时候并没有考虑到内存分配的问题,对内存具体没有过于深究,这次遇到了就好好解决一下。

猜你喜欢

转载自blog.csdn.net/Edwinwzy/article/details/131667902