为啥 sizeof(IO_ERROR_LOG_PACKET) == 48 而不是 44? [复制]

Posted

技术标签:

【中文标题】为啥 sizeof(IO_ERROR_LOG_PACKET) == 48 而不是 44? [复制]【英文标题】:Why is sizeof(IO_ERROR_LOG_PACKET) == 48 and not 44? [duplicate]为什么 sizeof(IO_ERROR_LOG_PACKET) == 48 而不是 44? [复制] 【发布时间】:2021-12-28 22:36:49 【问题描述】:
typedef struct _IO_ERROR_LOG_PACKET 
  UCHAR MajorFunctionCode; offset: 0 byte, size: 1 byte
  UCHAR RetryCount       ; offset: 1 byte, size: 1 byte
  USHORT DumpDataSize    ; offset: 2 byte, size: 2 byte
  USHORT NumberOfStrings ; offset: 4 byte, size: 2 byte
  USHORT StringOffset    ; offset: 6 byte, size: 2 byte
  USHORT EventCategory   ; offset: 8 byte, size: 2 byte + 2 byte for alignment
  NTSTATUS ErrorCode     ; offset: 12 byte, size: 4 byte
  ULONG UniqueErrorValue ; offset: 16 byte, size: 4 byte
  NTSTATUS FinalStatus   ; offset: 20 byte, size: 4 byte
  ULONG SequenceNumber   ; offset: 24 byte, size: 4 byte
  ULONG IoControlCode    ; offset: 28 byte, size: 4 byte
  LARGE_INTEGER DeviceOffset; offset: 32 byte, size: 8 byte
  ULONG DumpData[1]      ; offset: 40 byte, size: 4 byte
 IO_ERROR_LOG_PACKET, *PIO_ERROR_LOG_PACKET;

; total = 44 byte

我预计sizeof(IO_ERROR_LOG_PACKET) 是 44 字节。但是当我反汇编它时,它竟然是48个字节。有人知道为什么吗?

【问题讨论】:

【参考方案1】:

LARGE_INTEGER 需要与 8 字节边界对齐。成员在结构内对齐是不够的,而且结构要对齐到 8 字节也是不够的。为此,结构被填充为 8 字节(否则你会对这种结构的数组有问题):

typedef struct _IO_ERROR_LOG_PACKET 
  UCHAR MajorFunctionCode; 1 byte
  UCHAR RetryCount       ; 1 byte
  USHORT DumpDataSize    ; 2 byte
  USHORT NumberOfStrings ; 2 byte
  USHORT StringOffset    ; 2 byte
  USHORT EventCategory   ; 2 byte + 2 byte for alignment
  NTSTATUS ErrorCode     ; 4 byte
  ULONG UniqueErrorValue ; 4 byte
  NTSTATUS FinalStatus   ; 4 byte
  ULONG SequenceNumber   ; 4 byte
  ULONG IoControlCode    ; 4 byte
  LARGE_INTEGER DeviceOffset; 8 byte
  ULONG DumpData[1]      ; 4 byte + 4 byte for alignment
 IO_ERROR_LOG_PACKET, *PIO_ERROR_LOG_PACKET;

; total = 48 byte

见https://en.cppreference.com/w/c/language/object#Alignment

【讨论】:

但是为什么这会导致整个结构是8字节对齐的 因为否则它不能保证DeviceOffset的8字节对齐 请注意,LARGE_INTEGER 的大小为 8 个字节,这并不意味着它也是对齐要求。对结构体大小的另一种解释是,实现要求 all 结构体至少对齐 8 字节。

以上是关于为啥 sizeof(IO_ERROR_LOG_PACKET) == 48 而不是 44? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥 sizeof("-2147483648") - 1

为啥“memset(arr, -1, sizeof(arr)/sizeof(int))”不能将整数数组清除为-1?

为啥“memset(arr, -1, sizeof(arr)/sizeof(int))”不能将整数数组清除为-1?

为啥 sizeof 被认为是运算符?

一个物体有多大?为啥没有sizeof? [复制]

为啥 C++0x 中有 sizeof... 运算符?