【问题标题】:Values of padding bytes in CC中填充字节的值
【发布时间】:2021-04-10 17:16:37
【问题描述】:

我在这个小 C 程序中发现了一个奇怪的行为。我有 2 个结构,都有填充字节,但在不同的地方。

第一个结构具有索引 [1:3] 的填充字节,并且预期输出:静态变量被清零,因此填充值全为 0,堆栈上的局部变量在填充字节中留下垃圾值。示例输出:

Char is first, then int:
aa 60 8e ef ff ff ff ff 
aa 00 00 00 ff ff ff ff 

但是在第二个结构中,发生了一些奇怪的事情。此结构中的填充字节带有索引 [5:7],因此我预计非静态变量中有一些垃圾值,但每次输出都是:

Int is first, then char:
ff ff ff ff aa 7f 00 00 
ff ff ff ff aa 00 00 00 

为什么填充总是7f 00 00

完整的程序:

#include "stdio.h"
#include "stdint.h"
#include "stddef.h"

//  0 1 2 3 4 5 6 7
// |a|#|#|#|b|b|b|b|
typedef struct
{
    uint8_t a;
    uint32_t b;
} S1;

//  0 1 2 3 4 5 6 7
// |a|a|a|a|b|#|#|#|
typedef struct
{
    uint32_t a;
    uint8_t b;
} S2;

void print_bytes(void* mem, size_t num_bytes)
{
    for (size_t i = 0; i < num_bytes; i++)
        printf("%02x ", *((unsigned char*)mem + i));
    putc('\n', stdout);
}

int main()
{    
    S1 var1          = { .a = 0xAA, .b = 0xFFFFFFFF };
    static S1 var1_s = { .a = 0xAA, .b = 0xFFFFFFFF };

    printf("Char is first, then int:\n");
    print_bytes(&var1,   sizeof(S1));
    print_bytes(&var1_s, sizeof(S1));

    S2 var2          = { .a = 0xFFFFFFFF, .b = 0xAA };
    static S2 var2_s = { .a = 0xFFFFFFFF, .b = 0xAA };
    
    printf("\nInt is first, then char:\n");
    print_bytes(&var2,   sizeof(S2));
    print_bytes(&var2_s, sizeof(S2));
}

【问题讨论】:

  • 你的期望是错误的,填充字节总是包含垃圾。即使这个程序显示填充总是 7f 00 00 (或任何其他序列),但这并不意味着它不是垃圾值。

标签: c++ c byte padding


【解决方案1】:

如果我运行你的程序就没有问题。最后一个字节是随机的。这可能取决于您的系统。

【讨论】:

  • 是的,在询问之前应该检查不同系统上的输出。谢谢!
  • 这不是重点。即使stackoverflow上的每个人都尝试过并且具有相同的价值,它仍然是垃圾。如:下次升级编译器时,垃圾值可能会改变。或者它可能是几乎每个人都会尝试的 x86 实现的副作用。关键是:尝试它是没有意义的,因为重要的是规范说明了什么,而不是您的特定编译器是什么,您在特定平台上的特定选项最终会立即执行
  • @spectras 我想说的是,如果我至少检查了来自不同编译器的输出,这个问题不会因堆栈溢出而告终。第一个在线编译器已经显示了不同的输出。
猜你喜欢
  • 2020-11-07
  • 2013-11-14
  • 1970-01-01
  • 2019-07-18
  • 1970-01-01
  • 2011-08-01
  • 2013-11-12
  • 1970-01-01
  • 2018-01-14
相关资源
最近更新 更多