【发布时间】:2015-03-13 10:08:18
【问题描述】:
剧透只包含背景和上下文
! This post mentions,为了解决当对象超出范围时它被释放的事实,只需将对象返回堆栈分配的对象,使其保持在范围内。这显然会在其他地方的堆栈上复制对象。 This guy 甚至确认您应该始终更喜欢分配给堆栈。 在 C++ 中,使用类似:
!
Object* my_object = new Object();!动态地将一个对象实例化到堆中,然而 !
Object my_object = Object();!实例化堆栈上的对象。堆栈的大小是有限的,而堆实际上没有(除了物理限制)。而且,根据这个this post,堆栈访问时间要快得多,当然,当它超出范围时,释放是自动的。
我正在尝试创建一个速度绝对关键的应用程序,我不能只在 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;
}
编辑: 请参见下面的 cmets。当您从创建它的范围返回堆栈分配的对象时,会创建该对象的副本。那个副本也在堆栈上吗?如果我将该复制的对象分配给在 main 范围内声明的向量,该对象还会在堆栈上吗?
【问题讨论】:
-
can't I just instantiate all of my objects on the stack within main, and simply save every instantiation that's within a nested scope to an outside container?是的,当然可以。你的问题到底是什么? ,你写的代码很好。 -
"输出 1!它还在吗?" -- 我认为这让你感到惊讶吗?请注意,虽然向量本身在堆栈上,但它管理的对象却不在。内存管理细节在vector的成员函数中处理,这是应该的。当您执行
stack_nodes.push_back(Node(i));时,Node对象将被复制到堆上由向量对象管理的内存中。 -
“尝试创建一个速度至关重要的应用程序” - 尝试优雅地编写它,这对于初学者来说已经足够挑战了。然后担心速度如果你需要 - 使用分析器作为指导。您的程序可能已经比您需要的快得多,或者可能慢得多以至于更好的分配无法挽救它 - 至少您会知道自己所处的位置。
-
致所有刚刚回复的人:如果 Benjamin Lindley 是正确的,那么我的问题没有得到回答,至少不是很理想。如果将新堆栈分配的对象推送到向量中会从堆栈中删除该对象并将其副本放入堆中,那么为什么不直接动态分配呢?
-
因为那时你必须自己处理释放,这很麻烦而且容易出错。
标签: c++ memory-management scope stack