【问题标题】:How do compilers allocate memory for classes?编译器如何为类分配内存?
【发布时间】:2016-02-08 06:56:50
【问题描述】:

当我使用类指针创建一个类时:

class A{
    B* p_b1;
    B* p_b2;
    A(){}
}

我假设编译器为每个 A 实例生成至少 2 个指针大小的空间。我的问题是,如果它们不是指针而是直接向上的对象,例如:

class A{
    B b1;
    B b2;
    A(){}
}

编译器会在 A 类的内存空间内为 b1 和 b2 分配空间吗?或者它会在堆栈的其他地方声明实际的 B 类?

我问这个的原因是因为我正在尝试减少代码中的内存分配,并且正在徘徊是否会产生任何影响。

【问题讨论】:

  • 你在堆栈上的其他地方是什么意思?在您的示例中,b1、b2 是在堆栈上创建的。如果你想减少内存分配,那么使用更少的对象(包括在堆上创建的对象)
  • 编译器也从不分配空间。运行时间!
  • @Nandu 是的,但是机器需要在堆栈上为每个对象分配内存。因此,我不得不问它是否会概括分配以覆盖其中的所有对象。本质上是“共享”堆栈分配。
  • x86 机器不需要在堆栈上为每个对象分配内存。静态分配和使用堆是可选的。你的架构是什么?
  • 内存必须分配在某个地方,因此如果不减少内存中所需的内容量,就无法减少分配。也许您的意思是动态内存分配?或者你说的是内核分配的内存页数?

标签: c++ class memory-management


【解决方案1】:

这实际上取决于。任何作为对象字段的东西都将以与对象相同的方式分配(都在堆栈上或都在堆上)。如果您希望减少分配,您可以考虑重用对象。您可以手动调用析构函数,然后调用placement new 表达式来重用对象的内存。

另一方面,如果您希望简单地减少所用堆栈的大小,则在构造函数中在堆上分配并在析构函数中释放 (RAII)。

【讨论】:

    【解决方案2】:

    编译器会在A类的内存空间内为b1和b2分配空间吗?

    是的。

    或者它会在堆栈的其他地方声明实际的 B 类?

    没有。

    我问这个的原因是因为我正在尝试减少代码中的内存分配,并且正在徘徊是否会产生任何影响。

    是的,它会有所作为。在堆栈上分配内存比从堆中分配内存更有效。如果可以的话,当性能成为问题时,更喜欢堆栈而不是堆来分配内存。

    【讨论】:

    • 这不取决于问题吗?例如:对象向量与指针向量 - 堆栈与堆
    • 第二个例子效率更高,即使 A 类的对象是在堆上创建的,因为它会导致一个堆分配而不是三个。
    • @Nandu,当你有一个对象向量时,堆栈上没有多少。大部分内存都在堆上。如果你有一个指针向量,你就有两层堆内存,一层用于分配给向量“数据”的内存,一层用于对象本身。
    • 真的。但是您提到当性能成为问题时,更喜欢堆栈而不是堆。这如何适应不断增长的向量(或 STL 容器)的上下文?在这些情况下,堆上的对象没有提供更好的性能吗??
    • @Nandu,使用向量时,您无法选择“数据”的分配位置,它始终在堆上。这并没有比使用堆栈内存创建的数组提供更好的性能。它为您提供了其他好处 - 动态调整大小、创建更大数组的能力,浮现在脑海中。但它不会比在堆栈上创建一个数组更好。
    猜你喜欢
    • 2019-04-15
    • 1970-01-01
    • 2013-07-20
    • 1970-01-01
    • 1970-01-01
    • 2013-08-29
    • 2010-10-31
    • 1970-01-01
    相关资源
    最近更新 更多