【问题标题】:"the compiler will set aside 4 bytes for the variable even though the variable itself only requires 1 byte." Is it right?“即使变量本身只需要 1 个字节,编译器也会为变量留出 4 个字节。”这样对吗?
【发布时间】:2020-11-27 03:36:17
【问题描述】:

这是一个c++ 代码 sn-p。它显示空类实例的大小为1。 但这是我想知道的。如果考虑内存对齐并且每个对象或变量都分配在从例如 4 的倍数开始的内存区域。我们可以说instance_a 的大小为 1 字节但实际上占用 4 字节(我的意思是编译器即使变量本身只需要 1 个字节,也会为变量留出 4 个字节),因为尾部的 3 个字节不会成为其他变量内存区域的一部分(编译器不会触及,因为大多数时候它都有一个更好的选择)?

class A{};

int main(){
    A instance_a = A();
    cout << sizeof(instance_a) << endl;  // 1
    return 0;
}

更新:我已经阅读了 cmets。我知道A[] 数组很紧凑。我同意编译器做出最终决定。让我们只关注对象instance_a 而忘记A[] 数组。 instance_a(size == 1) 之后的 3 个字节是否有可能成为其他对象内存区域的一部分?我不认为编译器有充分的理由触及尾随的 3 个字节,因为这些字节不是 4 的倍数。如果一个对象从 3 个字节之一开始,则该对象不是内存对齐的。 --- 如果有更好的选择,编译器为什么要碰它?

update2:感谢 JaMiT 的评论。我的话不够准确。 “即使变量本身只需要1个字节,编译器也会为变量留出4个字节。”这就是我想要表达的。

【问题讨论】:

  • 不,你不能这么说。您的 C++ 编译器对如何对齐有最终决定权。
  • A a[2]; 占用 2 个字节还是 8 个字节或其他?这也取决于编译器。
  • 没有。编译器可能为该类型分配比sizeof 更多的内存,但标准并不要求这样做。实际上,如果结构类型对齐要求是 4 个字节,则大多数当前编译器默认情况下会调整类型的大小以避免此类事情(即,它们将填充放在类型中,而不是在它的实例之后)。但是,同样,这是编译器实现中的一个选择。
  • "让我们只关注对象instance_a" -- 如果你想关注instance_a,也许你想从编辑你的问题" [...] 每个对象或变量都被分配 [...]" 到只是 "[...] 每个变量都被分配 [...]"?
  • 如果我理解您的预期问题,您可能需要重新考虑您的用词选择。 “占用” 4 个字节的变量表明该变量扩展为填充所有 4 个字节。我认为您的意思更像是“消耗” 4 个字节或“需要” 4 个字节;这些更接近于暗示编译器将为变量留出 4 个字节,即使变量本身只需要 1 个字节。 (或者也许不要试图将所有含义都压缩到一个词中。)

标签: c++ operating-system


【解决方案1】:

我们可以说 instance_a 的大小是 1 个字节,但实际上占用了 4 个字节

没有。一个对象占用的内存量它的大小。然而,这可能与其成员大小的总和不同,即使对于 POD 对象也是如此。这种差异通常是您描述的对齐要求的结果。除了对齐成员或将对象的大小填充到某个目标值之外没有其他功能的字节称为“填充”。它们是对象表示的一部分。

让我们只关注对象 instance_a 而忘记 A[] 数组。 instance_a 的尾随 3 个字节是否有可能成为其他对象内存区域的一部分?

没有。如果instance_a 的大小为 4,则所有四个字节都属于该对象。部分或全部可以与其成员共享,但不与不是其成员的对象共享,除非instance_a 是联合的成员。

我的话不够准确。 “即使变量本身只需要 1 个字节,编译器也会为变量留出 4 个字节。”

编译器将为instance_a 的表示保留一个正好为sizeof instance_a 字节的连续区域。这是instance_a 需要的字节数,即使某些字节是填充的。一般来说,紧邻的其他对象可能有也可能没有存储,但不相关对象的存储不会与instance_a的存储重叠。如果instance_a 是包含 2 个或更多元素的数组的成员,存储至少一个紧邻的对象。

【讨论】:

    猜你喜欢
    • 2023-01-13
    • 2015-03-10
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 2011-05-26
    • 1970-01-01
    • 1970-01-01
    • 2016-09-02
    相关资源
    最近更新 更多