C++ 类内存模型和对齐

Posted

技术标签:

【中文标题】C++ 类内存模型和对齐【英文标题】:C++ Class Memory Model And Alignment 【发布时间】:2011-10-16 09:46:25 【问题描述】:

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

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

编辑:感谢您的所有回答。他们真的帮了很多忙。

【问题讨论】:

【参考方案1】:

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

对象的内存放置/对齐不取决于其类型是声明为class 还是struct。在 C++ 中 classstruct 之间的唯一区别是类默认具有 private 成员,而结构默认具有 public 成员。

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

我不确定您所说的“加载到内存中”是什么意思。然而,在一个对象内,编译器不允许重新排列变量。例如:

class Foo 
    int a;
    int b;
    int c;
;

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

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

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

函数不是数据,所以对齐不是他们关心的问题。在某些可执行文件格式和/或体系结构中,函数二进制代码实际上确实占据了与数据变量不同的区域,但 C++ 语言不知道这一事实。

一般来说,我会保留我所有的记忆对齐和位置 依赖的东西,如文件头和算法数据 结构。我只是想知道这是否是固有的 与结构一样的类以及它是否能很好地翻译 如果我选择使用这种方法,则进入课程。

内存对齐几乎是编译器自动为您处理的事情。它更像是一个实现细节,而不是其他任何东西。我说“几乎自动”是因为在某些情况下它可能很重要(序列化、ABI 等),但在应用程序中它不应该是一个问题。

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

【讨论】:

函数存储在内存中,如果我没记错的话(或分页文件)。我很想了解的另一件事是,当应用程序执行时,编译器如何决定在内存中对非内联函数(在大多数情况下并不重要)进行排序和定位。 @David Young:是的,它在内存中,但是编译器如何在内存中安排函数代码完全取决于实现。编译器之间甚至编译器版本之间的细节可能会发生变化!【参考方案2】:

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

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

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

是的。

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

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

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

好的。不确定这会如何影响任何事情。

我只是想知道这是否是类所固有的,还是结构所固有的

同一事物的类/结构不同的名称。

如果我选择使用这种方法,它是否能很好地转化为类。

选择什么方法?

【讨论】:

不完全在第二点。见***.com/questions/6577906/…——长话短说,访问说明符把整个事情搞砸了。【参考方案3】:

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

存储实例变量的确切方式取决于所使用的编译器,但它们通常倾向于按顺序排列。

【讨论】:

啊。这就是“this”指针发挥作用的地方。出于某种原因,我认为函数是相对于对象的第一个实例定位的。现在回想起来,这完全没有意义,而且我这么幼稚是愚蠢的,因为这意味着复制功能,或者至少意味着实现某种跟踪机制。无知是福。【参考方案4】:

C++ 类不参与“持久性”,如二进制模式结构,并且不应附加对齐。保持课程简单。 与类对齐可能会对性能产生负面影响,也可能会产生副作用。

【讨论】:

以上是关于C++ 类内存模型和对齐的主要内容,如果未能解决你的问题,请参考以下文章

C++虚基类表指针字节对齐模型

C++ 类和对象上

谈谈对象大小——从字节对齐到对象模型

C++语法小记---面向对象模型(实例的内存分布)

c++ 之 内存模型:对象篇

一文读懂C++虚继承的内存模型