C++ 如何计算存储在对象中的字节数

C++ 如何计算存储在对象中的字节数,c++,C++,假设我有下面的Foo类。Foo成员变量的大小是我所期望的。然而,FooIt自身的大小是16。额外的四个字节从哪里来 #include <iostream> #include <string> using namespace std; class Foo { public: int *data; int length; }; int main() { Foo f; cout << "Size

假设我有下面的Foo类。Foo成员变量的大小是我所期望的。然而,FooIt自身的大小是16。额外的四个字节从哪里来

#include <iostream>
#include <string>

using namespace std;

class Foo {
public:
        int *data;
        int length;
};

int main() {
        Foo f;
        cout << "Size of foo's data: " << sizeof(f.data) << endl;
        cout << "Size of foo's length: " << sizeof(f.length) << endl;
        cout << "Size of foo: " << sizeof(f) << endl;

        return 0;
}

编译器可以添加填充来对齐单词,这可能就是它的来源。您可以使用#pragma pack尝试消除它,但我不确定这是否可靠

编译器可以添加填充以对齐单词,这可能就是它的来源。您可以使用#pragma pack尝试消除它,但我不确定这是否可靠

编译器可以添加填充以对齐单词,这可能就是它的来源。您可以使用#pragma pack尝试消除它,但我不确定这是否可靠

编译器可以添加填充以对齐单词,这可能就是它的来源。您可以使用#pragma pack来尝试消除它,但我不确定这是否可靠

您看到了编译器为实现对齐而添加的“不可见”填充字节的证据


编译器喜欢在方便的边界(例如64位或8字节,在您的情况下)上对齐结构,以便更有效地访问其成员。如果要创建多个
Foo
对象的数组,则在本例中是如此;结尾填充将使每个字符的开头保持在8字节(64位)的边界上。如果该类中的字段大小不同,您可能还会看到出于相同目的在字段之间添加了额外的填充。

您看到了编译器为实现对齐而添加的“不可见”填充字节的证据


编译器喜欢在方便的边界(例如64位或8字节,在您的情况下)上对齐结构,以便更有效地访问其成员。如果要创建多个
Foo
对象的数组,则在本例中是如此;结尾填充将使每个字符的开头保持在8字节(64位)的边界上。如果该类中的字段大小不同,您可能还会看到出于相同目的在字段之间添加了额外的填充。

您看到了编译器为实现对齐而添加的“不可见”填充字节的证据


编译器喜欢在方便的边界(例如64位或8字节,在您的情况下)上对齐结构,以便更有效地访问其成员。如果要创建多个
Foo
对象的数组,则在本例中是如此;结尾填充将使每个字符的开头保持在8字节(64位)的边界上。如果该类中的字段大小不同,您可能还会看到出于相同目的在字段之间添加了额外的填充。

您看到了编译器为实现对齐而添加的“不可见”填充字节的证据



编译器喜欢在方便的边界(例如64位或8字节,在您的情况下)上对齐结构,以便更有效地访问其成员。如果要创建多个
Foo
对象的数组,则在本例中是如此;结尾填充将使每个字符的开头保持在8字节(64位)的边界上。如果该类中的字段大小不同,您可能还会看到出于相同目的在字段之间添加了额外的填充。

编译器可以在结构字段之间添加填充,例如,确保成员在4字节或8字节边界上对齐。@Jim Lewis什么是结构字段?“字段”与“数据成员”。编译器可以在结构字段之间自由添加填充,例如,确保成员在4字节或8字节边界上对齐。@Jim Lewis什么是结构字段?“字段”与“数据成员”相同“。编译器可以在结构字段之间自由添加填充--例如,确保成员在4字节或8字节边界上对齐。@Jim Lewis什么是结构字段?“字段”与“数据成员”相同。编译器可以在结构字段之间自由添加填充--例如,为了确保成员在4字节或8字节边界上对齐。@Jim Lewis什么是结构字段?“字段”与“数据成员”相同。很有趣。因此,如果我要添加另一个int成员变量,使Foo的大小为8的倍数,那么编译器就不需要添加填充了?@ChrisD:很好的后续问题。可能吧,但在这种情况下,编译器可能希望向两个
int
字段添加填充,以便对字段的任何访问都以相同的方式进行8字节对齐,从而使类的大小为24字节。视情况而定。:)对于这种布局,编译器可以有相当大的自由度,您应该尝试一下,看看会发生什么。你也可以查看每个成员的地址,看看他们之间的距离有多近。很酷。是的,当我添加另一个int时,我的Foo对象的大小变成了16。另外,在打印地址时,它们是按您所说的8字节对齐的。谢谢你的洞察力。很有趣。因此,如果我要添加另一个int成员变量,使Foo的大小为8的倍数,那么编译器就不需要添加填充了?@ChrisD:很好的后续问题。可能吧,但在这种情况下,编译器可能希望向两个
int
字段添加填充,以便对字段的任何访问都以相同的方式进行8字节对齐,从而使类的大小为24字节。视情况而定。:)对于这种布局,编译器可以有相当大的自由度,您应该尝试一下,看看会发生什么。你也可以查看每个成员的地址,看看他们之间的距离有多近。很酷。是的,当我添加另一个int时,我的Foo对象的大小变成了16。另外,在打印地址时,它们是按您所说的8字节对齐的。谢谢你的洞察力。很有趣。因此,如果我要添加另一个int成员变量maki,编译器就不需要添加填充
        Size of foo's data: 8 
        Size of foo's length: 4 
        Size of foo: 16