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

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

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

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

【问题讨论】:

    标签: c++ arrays memory position alignment


    【解决方案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】:

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

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

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

    是的。

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

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

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

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

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

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

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

    选择什么方法?

    【讨论】:

    【解决方案3】:

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

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

    【讨论】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-29
      • 1970-01-01
      • 2017-11-15
      • 1970-01-01
      • 2015-09-24
      • 1970-01-01
      • 2018-07-22
      • 1970-01-01
      相关资源
      最近更新 更多