3

我有一个对象(A),它有一个由对象(B)组成的列表。list(B) 中的对象是指针,但列表本身应该是指针吗?我正在从 Java 迁移到 C++,但还没有完全习惯堆栈/堆。该列表不会传递到 A 类之外,只会传递列表中的元素。为了以防万一,将列表本身分配在堆上是一种好习惯吗?

另外,包含 list(A) 的类也应该在堆本身上吗?像列表一样,它不会被传递。

4

5 回答 5

6

请记住,

  1. 仅当 Object-A 也在堆栈上时,列表才会在堆栈上
  2. 即使列表本身不在堆上,它也可以从堆中分配其存储空间。这就是 std::list、std::vector 和大多数 C++ 列表的工作方式——原因是基于堆栈的元素不能增长。
  3. 现在大多数堆栈都在 1mb 左右,所以在你需要担心它之前,你需要一个相当大的对象列表。即使您的堆栈只有大约 32kb,您也可以存储近 8000 个指针,以免成为问题。

不熟悉 C/C++ 中显式内存管理的 IMO 人员可能倾向于过度思考这些事情。

除非您正在编写一些您知道会有数千个相当大的对象的东西,否则只需将列表放入堆栈中。除非您在函数中使用巨大的 C 样式数组,否则由于上面的 #1 和 #2,列表使用的内存可能最终会出现在堆中。

于 2009-03-15T02:01:08.387 回答
1

你最好在堆上存储一个列表,如果它可以增长的话。由于您永远不知道运行时堆栈将是什么,因此溢出是一种真正的危险,其后果是致命的。

如果您绝对知道列表的上限,并且与堆栈的大小相比它很小,那么您可能可以避免堆栈分配列表。

于 2009-03-15T01:51:51.840 回答
0

我在堆栈可能很小并且需要避免堆碎片的环境中工作,所以我会使用这些规则:

  • 如果列表很小并且已知固定大小,则堆叠。

  • 如果列表很小且固定大小未知,则可以同时考虑堆和 alloca()。如果您可以保证您的函数在您的分配将在那里的持续时间内不会在堆上分配任何东西,那么使用堆将是一个不错的选择。如果你不能保证这一点,你要求一个片段,而 alloca() 将是一个更好的选择。

  • 如果列表很大或需要增长,请使用堆。如果你不能保证它不会碎片,我们倾向于在我们的内存管理器中内置一些资源,例如自上而下的分配和单独的堆。

大多数情况并不要求人们担心碎片,在这种情况下,他们可能不推荐使用 alloca。

对于包含列表的类,如果它在函数范围内是本地的,只要内部数据结构不是非常大,我会将它放在堆栈上。

于 2009-03-15T02:00:19.557 回答
0

“列表”是什么意思。如果它是 std::list (或 std::vector 或任何其他 STL 容器),那么它不会在堆栈上存储任何东西,所以不用担心。

如果您有任何疑问,请查看 sizeof(A) ,它会告诉您它在堆栈上时将使用多少内存。

但是......决定应该主要基于对象的生命周期。基于堆栈的对象一旦超出范围就会被销毁。

于 2009-03-15T02:07:43.020 回答
-1

堆栈总是最简单的。不幸的是,它有一个很大的缺点——你必须提前知道元素的数量。

于 2009-03-15T01:51:35.740 回答