Som*_*bie 18 c++ variables heap stack
我前段时间和朋友讨论过.他是一位经验丰富的C++用户,我不是一位经验丰富的C++用户.他告诉我,我应该努力使用堆变量,即:
A* obj = new A("A");
Run Code Online (Sandbox Code Playgroud)
而不是:
A obj("A");
Run Code Online (Sandbox Code Playgroud)
除了使用指针很好和灵活的所有东西之外,他说最好把东西放在堆而不是堆栈中(关于堆栈的东西比堆小?).这是真的吗?如果是这样的话?
编辑:我写了一个错字,说我的朋友建议堆栈变量.他推荐堆变量.
Edit2:我知道有关生命的问题.让我们假设我已经适当地管理了这些变量的生命周期.(即关注的唯一标准是堆与堆栈存储,没有生命周期问题)
Abh*_*t_K 13
根据上下文,我们需要使用堆或堆栈.每个线程都获得一个堆栈,线程通过调用函数来执行指令.调用函数时,函数变量将被推送到堆栈.当函数返回堆栈回滚并回收内存时.现在线程局部堆栈有一个大小限制,它有所不同,可以在某种程度上进行调整.如果在堆栈上创建每个对象并且对象需要大内存,则考虑到此限制,则堆栈可能会耗尽,从而导致堆栈溢出错误.除此之外,如果要通过多个线程访问对象,则将这样的对象存储在堆栈上是没有意义的.
因此,小变量,小对象和指针应存储在堆栈中.将对象存储在堆或免费存储上的问题是,内存管理变得困难.内存泄漏的可能性很大,这很糟糕.此外,如果应用程序尝试访问已删除的对象,则可能会发生访问冲突,从而导致应用程序崩溃.
C++ 11引入了智能指针(共享,唯一),使堆内存管理更容易.实际引用的对象在堆上,但是由智能指针封装,该指针始终在堆栈上.因此,当函数返回事件期间或异常期间堆栈回滚时,智能指针的析构函数会删除堆上的实际对象.在共享指针的情况下,保持引用计数,并且当引用计数为零时删除实际对象. http://en.wikipedia.org/wiki/Smart_pointer
该堆栈应者优先的堆,如堆栈分配的变量是自动变量:当程序进入了他们的背景下销毁是自动完成的.
实际上,在堆栈和堆上创建的对象的生命周期是不同的:
{}(未由new分配)位于堆栈中.从函数返回时它们会自动销毁.(他们的析构函数被调用,他们的记忆被释放).例:
void myFun()
{
A onStack; // On the stack
A* onHeap = new A(); // On the heap
// Do things...
} // End of the function onStack is destroyed, but the &onHeap is still alive
Run Code Online (Sandbox Code Playgroud)
在此示例中,onHeap在函数结束时仍将分配其内存.这样,如果你没有指向onHeap某个地方的指针,你将无法删除它并释放内存.这是内存泄漏,因为在程序结束之前内存将丢失.
但是,如果要返回指针onStack,因为onStack在退出函数时被销毁,使用指针可能会导致未定义的行为.虽然使用onHeap仍然完全有效.
为了更好地理解堆栈变量的工作方式,您应该搜索有关调用堆栈的信息,例如维基百科上的这篇文章.它解释了如何堆叠变量以在函数中使用.
对于使用堆栈分配的变量还是堆分配的变量,没有通用的规则。只有准则,具体取决于您要执行的操作。
这是一些优点和缺点:
堆分配:
优点:
缺点:
堆栈分配:
优点:
缺点:
我认为这体现了一些利弊。我敢肯定还有更多。
最后,这取决于您的应用程序需求。