c++类内存模型和对齐

C++ Class Memory Model And Alignment

本文关键字:对齐 模型 内存 c++      更新时间:2023-10-16

我有几个关于c++中的数据位置和对齐的问题要问。类是否具有与结构体相同的内存位置和内存对齐格式?

更具体地说,数据是根据声明的顺序加载到内存中的吗?函数是否会影响内存对齐和数据位置,或者它们是否被分配到另一个位置?一般来说,我将所有内存对齐和位置相关的东西,如文件头和算法数据保存在结构体中。我只是想知道这是否是类固有的,因为它是结构体,如果我选择使用这种方法,它是否会很好地转化为类。

编辑:谢谢你的回答。他们真的帮了大忙。

类是否具有相同的内存位置和内存对齐格式结构体?

对象的内存位置/对齐并不取决于它的类型是声明为class还是struct。c++中classstruct的唯一区别是,类默认有private个成员,而结构默认有public个成员。

更具体地说,是数据根据进入的顺序加载到内存中哪个是声明的?

我不知道你说的"加载到内存中"是什么意思。但是,在对象中,编译器不允许重新排列变量。例如:

class Foo {
    int a;
    int b;
    int c;
};

变量c必须位于b之后,b必须位于Foo对象的a之后。当创建Foo时,它们也按照类声明中所示的顺序构造(初始化),当销毁Foo时,它们以相反的顺序销毁。

由于继承和访问修饰符,它实际上比这更复杂,但这是基本思想。

函数是否影响内存对齐和数据位置分配到另一个位置?

函数不是数据,所以对它们来说对齐不是问题。在某些可执行文件格式和/或体系结构中,函数二进制代码实际上与数据变量占据了单独的区域,但c++语言对这一事实并不知情。

一般来说,我保留所有的内存对齐和位置依赖的东西,比如文件头和算法数据结构体。我只是想知道这是否是内在的类的结构,以及它是否可以很好地转换如果我选择使用这种方法,

内存对齐是编译器几乎自动为你处理的事情。它更像是一个实现细节。我之所以说"几乎自动",是因为在某些情况下它可能很重要(序列化、abi等),但在应用程序中它不应该成为一个问题。

关于读取文件(因为您提到了文件头),听起来像是将文件直接读取到struct占用的内存中。我不推荐这种方法,因为填充和对齐问题可能会使您的代码在一个平台上工作,而不是在另一个平台上工作。相反,您应该一次从文件中读取几个原始字节,并通过简单的赋值将它们分配到struct中。

类是否具有与结构体相同的内存位置和内存对齐格式?

是的。从技术上讲,类和结构之间没有区别。唯一的区别是默认的成员访问规范,否则它们是相同的。

更具体地说,数据是根据声明的顺序加载到内存中的吗?

是的。

函数是否影响内存对齐和数据位置,或者它们是否被分配到另一个位置?

。它们不影响对齐。方法是单独编译的。对象不包含任何对方法的引用(对于那些说虚拟表确实影响成员的人,答案是肯定的或否定的,但这是一个实现细节,不影响成员之间的相对差异。)编译器被允许向对象添加特定于实现的数据)。

一般来说,我将所有内存对齐和位置相关的东西,如文件头和算法数据保存在结构体中。

OK。我不知道这有什么影响。

我只是想知道这是否是类的内在,因为它是结构

类/结构相同的东西有不同的名字

,以及如果我选择使用这种方法,它是否会很好地转换为类。

选择什么方法?

c++类简单地转换为结构体,所有的实例变量作为结构体中包含的数据,而所有的函数都与类分离,并被视为接受这些结构体作为参数的函数。

实例变量的确切存储方式取决于所使用的编译器,但它们通常是有序的。

c++类不参与"持久化",就像二进制模式结构一样,不应该对它们进行对齐。保持类的简单。与类对齐可能会带来负面的性能好处,也可能有副作用。