c++ - 将结构体成员声明为 uint32_t 时的额外字节

标签 c++ struct sizeof structure-packing

我在使用 stdint.h 库中的 uint32_t 类型时遇到问题。如果我运行以下代码(在 Ubuntu linux 11.10 x86_64,g++ 版本 4.6.1 上):

#include "stdint.h"
#include <iostream>
using std::cout;
typedef struct{
    // api identifier
    uint8_t api_id;

    uint8_t frame_id;
    uint32_t dest_addr_64_h;
    uint32_t dest_addr_64_l;
    uint16_t dest_addr_16;
    uint8_t broadcast_radius;
    uint8_t options;
    // packet fragmentation
    uint16_t order_index;
    uint16_t total_packets;
    uint8_t rf_data[];
} xbee_tx_a;

typedef struct{
    // api identifier
    uint8_t api_id;

    uint8_t frame_id;
    uint16_t dest_addr_64_h;
    uint16_t dest_addr_64_l;
    uint16_t dest_addr_16;
    uint8_t broadcast_radius;
    uint8_t options;
    // packet fragmentation
    uint16_t order_index;
    uint16_t total_packets;
    uint8_t rf_data[];
} xbee_tx_b;


int main(int argc, char**argv){

   xbee_tx_a a;

   cout<<"size of xbee_tx_a "<<sizeof (xbee_tx_a)<<std::endl;
   cout<<"size of xbee_tx_a.api_id "<<sizeof (a.api_id)<<std::endl;
   cout<<"size of xbee_tx_a.frame_id "<<sizeof (a.frame_id)<<std::endl;
   cout<<"size of xbee_tx_a.dest_addr_64_h "<<sizeof (a.dest_addr_64_h)<<std::endl;
   cout<<"size of xbee_tx_a.dest_addr_64_l "<<sizeof (a.dest_addr_64_l)<<std::endl;
   cout<<"size of xbee_tx_a.dest_addr_16 "<<sizeof (a.dest_addr_16)<<std::endl;
   cout<<"size of xbee_tx_a.broadcast_radius "<<sizeof (a.broadcast_radius)<<std::endl;
   cout<<"size of xbee_tx_a.options "<<sizeof (a.options)<<std::endl;
   cout<<"size of xbee_tx_a.order_index "<<sizeof (a.order_index)<<std::endl;
   cout<<"size of xbee_tx_a.total_packets "<<sizeof (a.total_packets)<<std::endl;
   cout<<"size of xbee_tx_a.rf_data "<<sizeof (a.rf_data)<<std::endl;

   cout<<"----------------------------------------------------------\n";

   xbee_tx_b b;
   cout<<"size of xbee_tx_b "<<sizeof (xbee_tx_b)<<std::endl;
   cout<<"size of xbee_tx_b.api_id "<<sizeof (b.api_id)<<std::endl;
   cout<<"size of xbee_tx_b.frame_id "<<sizeof (b.frame_id)<<std::endl;
   cout<<"size of xbee_tx_b.dest_addr_64_h "<<sizeof (b.dest_addr_64_h)<<std::endl;
   cout<<"size of xbee_tx_b.dest_addr_64_l "<<sizeof (b.dest_addr_64_l)<<std::endl;
   cout<<"size of xbee_tx_b.dest_addr_16 "<<sizeof (b.dest_addr_16)<<std::endl;
   cout<<"size of xbee_tx_b.broadcast_radius "<<sizeof (b.broadcast_radius)<<std::endl;
   cout<<"size of xbee_tx_b.options "<<sizeof (b.options)<<std::endl;
   cout<<"size of xbee_tx_b.order_index "<<sizeof (b.order_index)<<std::endl;
   cout<<"size of xbee_tx_b.total_packets "<<sizeof (b.total_packets)<<std::endl;
   cout<<"size of xbee_tx_b.rf_data "<<sizeof (b.rf_data)<<std::endl;
}

然后我得到以下输出:

size of xbee_tx_a 20
size of xbee_tx_a.api_id 1
size of xbee_tx_a.frame_id 1
size of xbee_tx_a.dest_addr_64_h 4
size of xbee_tx_a.dest_addr_64_l 4
size of xbee_tx_a.dest_addr_16 2
size of xbee_tx_a.broadcast_radius 1
size of xbee_tx_a.options 1
size of xbee_tx_a.order_index 2
size of xbee_tx_a.total_packets 2
size of xbee_tx_a.rf_data 0
----------------------------------------------------------
size of xbee_tx_b 14
size of xbee_tx_b.api_id 1
size of xbee_tx_b.frame_id 1
size of xbee_tx_b.dest_addr_64_h 2
size of xbee_tx_b.dest_addr_64_l 2
size of xbee_tx_b.dest_addr_16 2
size of xbee_tx_b.broadcast_radius 1
size of xbee_tx_b.options 1
size of xbee_tx_b.order_index 2
size of xbee_tx_b.total_packets 2
size of xbee_tx_b.rf_data 0

我正在做的是打印出结构体的总大小以及结构体每个成员的大小。

对于 xbee_tx_b,成员的大小加起来等于结构的大小 (14)

对于 xbee_tx_a,成员的大小加起来为 18 个字节...但结构的大小为 20 个字节!

xbee_tx_a 和 xbee_tx_b 之间的唯一区别在于 dest_addr_64_X 成员的类型。它们是xbee_tx_a中的uint32_t和xbee_tx_b中的uint16_t。当我使用 uint32_t 时,为什么结构体的大小大于其成员大小的总和?这 2 个额外字节从哪里来?

谢谢!

最佳答案

结构体被填充为 4 字节的整数倍1,以便它们字对齐。 http://en.wikipedia.org/wiki/Data_structure_alignment#Data_structure_padding

另请参阅:


1 作为 @Mooing Duck评论说,这并不总是正确:

It's not always a multiple of 4 bytes, it varies (slightly) depending on the members. On the other hand, 99% of the time it's a multiple of 4 bytes.

关于c++ - 将结构体成员声明为 uint32_t 时的额外字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7970383/

相关文章:

c++ - 将字符串与 regEx 通配符值进行比较

C++ 从文件中获取数据以记住上次 session

c - 如何在 C 中将 void 指针转换为结构?

c++ - 确定动态内存分配中 char 指针的最大容量

c - sizeof 程序有什么问题

c++ - 可移植打印和比较 pthread_t

c++ - 这个 typedef 是如何工作的?

指针返回问题的 c++ 协方差问题

C 常量结构,在堆栈上包含不同长度的数组

c++ - size_t 和 sizeof 不一致