【问题标题】:Should we allocate memory for an object on heap when its internal memory already allocated in heap?当对象的内部内存已经在堆中分配时,我们是否应该在堆上为对象分配内存?
【发布时间】:2011-06-03 05:09:03
【问题描述】:

如果我使用 std::vector 或 std::string,我是否也需要在堆中分配它们。例如:

int main() {
    std::vector<int>* p = new std::vector<int>();
    delete p;
}

在 Java 和 C# 中,对象总是使用这种语法在堆中分配。我想知道在 C++ 中做同样的事情是否有效?因为每当我在 C++ 中创建一个类时,我通常会在堆栈和堆变量之间混合使用。比方说:

class simple {
    int a;
    double b;
    std::string c;
    std::vector<int> d;
    ....
};

我想知道在 C++ 中使用对象时应该遵循的最佳做法是什么?

  • 所有数据都应该在堆上分配?
  • 所有数据都可以混合吗?
  • 或者...

谢谢,

【问题讨论】:

  • 实际上,使用 C# 中的语法,对象不一定在堆上。如果是值类型,就会入栈。

标签: c++


【解决方案1】:

我尽量在堆栈上分配对象,因为在这种情况下我不必担心释放内存。只有当我明确想要控制对象的生命周期时,我才会在堆上分配对象。即使对象内部在堆上分配内存,您仍然可以在堆栈上创建对象本身。对此没有任何限制。

【讨论】:

    【解决方案2】:

    您应该避免在堆栈上创建大尺寸的对象,因为压力(大量输入数据)的偶然堆栈溢出很少通过测试发现,因此会让您的最终用户对您的软件崩溃感到不满。

    关于 string 和 vector 以及其他 STL 容器您不必担心,因为它们在内部使用动态分配。所以答案是否定的,将它们构建到堆栈中是安全的,而动态分配它们通常是矫枉过正的。

    可能有危险的是静态大小的数组,包含诸如 boost::array 之类的数组或具有诸如数据成员之类的类的东西。专家经常使用 pimpl idiom 使他们的类在内部动态化。

    堆栈速度非常快,但仅在真正有利于性能的地方使用它的速度。小心使用它会更安全。避免使用诸如“我在堆栈上分配所有内容”之类的危险习语。

    【讨论】:

    • +1 安全的好建议。我开发的一个平台将新 pthread 线程的默认堆栈大小设置为 64K。过去我犯了新手错误,即在堆栈上分配过大的缓冲区,这会导致出现各种奇怪的错误。
    【解决方案3】:

    没有;一般来说,除非变量的生命周期超过函数的生命周期,否则使用堆栈。

    容器类会从堆中分配它们自己的内存;堆栈上唯一的数据是容器类需要的任何簿记,例如指向头部的指针、大小等。

    此外,我建议避免手动新建/删除并使用 shared_ptr 等技术。

    【讨论】:

      猜你喜欢
      • 2011-09-13
      • 2013-08-10
      • 2017-11-08
      • 1970-01-01
      • 2021-03-20
      • 1970-01-01
      • 2015-10-15
      • 2010-10-31
      • 2017-12-06
      相关资源
      最近更新 更多