繁体   English   中英

为什么不总是实例化堆栈上的对象? C ++

[英]Why not always instantiate objects on the stack? C++

剧透只包含背景和上下文

这篇文章提到 ,要避免这样的事实,即当对象超出范围时,它会被释放,只需将对象返回堆栈分配的对象,使其保留在范围内即可。 显然,这会在其他位置在堆栈上复制对象。 这个家伙甚至确认您应该始终喜欢分配到堆栈。 在C ++中,使用类似以下内容的代码:

Object* my_object = new Object();

动态地实例化一个对象到堆,但是! Object my_object = Object();

实例化堆栈上的对象。 堆栈的大小受到限制,而堆实际上没有限制(物理限制除外)。 而且,根据这篇文章 ,堆栈访问时间要快得多,并且当超出范围时,当然释放是自动的。


我正在尝试创建一个对速度绝对至关重要的应用程序,难道我不能只在main内实例化堆栈上的所有对象,而只是将嵌套范围内的每个实例保存到外部容器中吗?

我使用包含属性“ id”的简单Node类自己对此进行了测试。 我实例化了堆栈上的节点,将它们放在向量中,这样就不会释放它们,然后(只是检查)我将新项目分配到堆栈,然后检查以确保仍然存在先前分配的数据。 我可以继续在一个规模较大的问题上实现这一点吗?

int main()
{
  vector<Node> stack_nodes;
  for (int i = 0; i < 2; ++i)
  {
    stack_nodes.push_back(Node(i)); // push newly copied stack-allocated objects so they don't die 
  }
  Node new_node1 = Node(3); // allocate two more to test stack memory overwriting 
  Node new_node2 = Node(4);
  cout << stack_nodes.at(1).getID(); // outputs 1! It's still there?
  return 0;
}

编辑:请参阅下面的评论。 从创建它的作用域返回堆栈分配的对象时,将创建该对象的副本。 该副本是否也在堆栈上? 如果我将复制的对象分配给在main范围内声明的向量,该对象是否仍在堆栈中?

我不能只实例化main中堆栈上的所有对象吗?

如果您可以说明所有需要的对象,则可以

哎呀,COBOL采取了这种方法。 “这是您永远需要的每个变量……”

我可以继续在一个规模较大的问题上实现这一点吗?

有无限的内存,是的。 总是。

使用有限的内存,您可能需要管理对象的生存期,并且仅在任何时候都需要实际需要的内存。

在某些情况下,您当然可以对某些程序执行此操作。 举例来说,回想过去,Fortran的定义是为了使程序使用的所有数据可以静态分配(这是常规方式)。

同时,这是非常有限的并且有问题。 仅举几个例子,它排除了(几乎)所有递归,这对于处理某些类型的递归数据结构(例如树)确实非常方便。

这也意味着所有变量实际上都是全局变量,因此(例如)程序中的任何代码都可以读取和/或写入程序中的几乎任何变量。 具有使用该模型的Fortran和BASIC(早期版本)等语言的经验表明,开发当前被视为中小型程序的程序需要大量的纪律,并且开发通常被视为大型系统的程序可能几乎不可能。 代码不同部分之间的依赖关系变得如此复杂,以至于几乎不可能确定在哪里使用了什么,哪些部分取决于其他部分等等。

我怀疑这在实践中是否合理。 分配堆栈空间的开销开出如此微不足道是消除它根本不会受到任何显着的程度的提高速度。 实际上,它可能很容易做到相反。 预分配变量意味着(必不可少的)每个变量都将驻留在内存的唯一部分中。 在给定的时间中,它们中的很大一部分将用于当前不在缓存中的内存部分,因此您最终会遇到较差的引用局部性,从而导致较差的缓存使用率。

输入函数时分配本地数据意味着大多数变量都位于栈顶或栈顶附近。 由于您几乎一直在使用靠近堆栈顶部的内存,因此该内存大部分时间都保留在缓存中,因此几乎所有的内存访问都命中了缓存。

分配时间通常(远远)低于1%,但是访问主内存而不是高速缓存的代价通常至少是10倍,并且通常要高得多(通常20到50倍)。 根据数据访问方式的不同,里程数会有所不同,但是您有巨大的潜在巨大损失,(最多)只有很小的机会获得微不足道的收益。

简介:这是一个糟糕的想法。 容易做了很多的伤害比好,甚至一点点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM