【问题标题】:Can the struct padding be safely used by the user code?用户代码可以安全地使用结构填充吗?
【发布时间】:2011-01-02 01:37:23
【问题描述】:

假设我有如下结构:

struct Struct {
    char Char;
    int Int;
};

并且sizeof( int ) 大于一并且编译器为Char 成员变量添加填充 - 编译器生成的代码是否允许更改填充字节的值?

我的意思是,如果我使用指针算法并将一些数据写入 Char 成员变量周围的填充字节,然后再进行 variable.Char = 赋值,编译器生成的代码可能还会覆盖一些填充字节?

【问题讨论】:

  • @nobugz,我认为这是一个有效的问题。在设置值之前您已将结构设置为 0 的图像,然后您可以稍后使用 memcmp 比较两个结构,但前提是编译器不接触填充字节。
  • 不要乱用填充,memsetmemcpy 使用类和结构。 更安全更健壮的方法是实现读取和写入打包缓冲区的方法(例如unsigned char[])。保险值得额外的可执行空间和时间。
  • @Thomas Matthews,我想你误解了我的意思。我在谈论比较两个结构,请参阅stackoverflow.com/questions/141720/…
  • 如果您关心字节对齐,大多数编译器允许您显式声明它。例如,在 VS 中,您可以使用 #pragma pack(1) 告诉编译器完全按照声明的方式打包您的结构,而无需额外填充。在这种情况下,sizeof(Struct) 将恰好是 sizeof(char)+sizeof(int),仅此而已。我见过使用这种机制的唯一有效用途是套接字编程,但我确信还有其他原因。

标签: c++ c struct alignment padding


【解决方案1】:

以下句子错误:不,它不会覆盖填充字节。但使用它可能不是一个好习惯。如果需要,可以在里面添加成员变量。

我根据 cmets 进行了研究,表明(正确)我很愚蠢:

C 标准有一个“附件 J”,其中包含 J.1 未指定行为部分。它说,“在结构或联合中存储值时填充字节的值”。这意味着编译器可以生成它想要将数据写入结构的任何指令,这可能允许它覆盖成员之后的填充。

【讨论】:

  • 没有什么可以阻止编译器覆盖填充。
  • 过失。你是对的。没有什么可以阻止它。 C 标准的附件 J 将“结构中填充字节的值”列为未指定。
【解决方案2】:

你当然可以在那里写一些东西,memset-ing 一个这样的结构的实例就可以了。但是,这样做并不安全,也不是一个好主意。有一天,另一个开发人员在某处放置#pragma 或在结构声明中添加一个成员,您的代码将以许多奇怪而奇特的方式爆炸,这可能需要相当长的时间来调试。

【讨论】:

    【解决方案3】:

    如果编译器足够聪明,可以使用单词 write 来保存 char 会怎样?您精心保存的数据将会丢失。 ;-)

    【讨论】:

    • 对,我认为这就是问题所在。编译器是否允许这样做?
    • 编译器显然被允许这样做。我更新了我的不正确答案以表明尽可能多的内容,并对此表示赞同。
    【解决方案4】:

    这样做的唯一原因是某个插件恶意欺骗主机应用程序存储额外数据。

    但不要这样做,因为在未来的某个时候它坏掉,这对所有相关人员来说都会是一件非常头疼的事情。

    【讨论】:

      猜你喜欢
      • 2016-01-25
      • 1970-01-01
      • 1970-01-01
      • 2019-09-18
      • 1970-01-01
      • 1970-01-01
      • 2018-09-30
      • 2023-01-17
      • 1970-01-01
      相关资源
      最近更新 更多