C ++堆栈与堆分配 [英] C++ stack vs heap allocation

查看:194
本文介绍了C ++堆栈与堆分配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道我应该在C ++中在堆栈上分配一个类吗?我在Java中有很强的背景,在Java中,所有类都使用 new 关键字在堆上分配。在C ++中,我可以在堆栈和堆分配之间选择,但是现在智能指针被引入,更有意义的是,分配不通过 std :: unique_ptr 传递所有权的所有内容。



我真的不能想到任何情况,使用堆栈分配是必要的或更好的。

解决方案

每当函数作用域或作用域的范围使用自动控制块,例如用于同时如果等等在函数内部 - 是对象需要的生命周期的良好匹配。这样,如果对象拥有/控制任何资源,例如动态分配的内存,文件句柄等 - 它们将在析构函数调用期间被释放,因为该范围被留下。



只有使用 new 才能清除垃圾回收器需要,例如:




  • 需要对象的活期长于函数范围,

    b $ b
  • 将所有权移交给其他某些代码


  • 以拥有指向基类的指针容器, (即使用虚拟分派到派生类函数实现),或


  • 一个特别大的分配将占用大量的堆栈已通过协商限制,通常在1-8 MB范围内)




    • 如果这是您使用动态分配,并且你希望对象的生命周期绑定到你的函数中的范围,你应该使用本地 std :: unique_ptr<> 来管理动态内存,并确保它被释放,无论你如何离开范围: return throw break 等。(您还可以在类中使用 std :: unique_ptr<> code> / struct 以管理对象拥有的任何内存。)




下面关于C ++ 11移动语义的评论 - 相关性是,如果你有一个小的管理对象在堆栈上控制大量的动态分配堆)内存,移动语义授予额外的保证和细粒度控制,当管理对象将其资源移交给由其他代码(通常是调用者,但是潜在地一些其他容器/对象寄存器)拥有的另一个管理对象时。这种切换可以避免即使瞬间复制/复制堆上的数据。此外, elision 返回值优化通常允许名义上自动/堆栈托管的变量直接在它们最终被分配/返回的内存中构造,而不是以后复制。


I was wondering when should I allocate a class on the stack in C++? I have a strong background in Java and in Java all classes are allocated on the heap, using the new keyword. In C++ I can pick between stack and heap allocation but now that smart pointers are introduced, it makes more sense to allocate everything that doesn't transfer ownership with std::unique_ptr.

I can't really think of any cases, where it would be necessary or better to use stack allocation. Maybe for some kind of optimisation in embedded systems?

解决方案

Use automatic (stack) allocation whenever the function scope - or the scope of a control block such as a for, while, if etc. inside the function - is a good match for the lifetime the object needs. That way, if the object owns/controls any resources, such as dynamically allocated memory, file handles etc. - they will be freed during the destructor call as that scope is left. (Not at some unpredictable later time when a garbage collector winds up).

Only use new if there's a clear need, such as:

  • needing the object to live longer than the function scope,

  • to hand over ownership to some other code

  • to have a container of pointers to base classes that you can then process polymorphically (i.e. using virtual dispatch to derived-class function implementations), or

  • an especially large allocation that would eat up much of the stack (your OS/process will have "negotiated" a limit, usually in the 1-8+ megabyte range)

    • if this is the only reason you're using dynamic allocation, and you do want the lifetime of the object tied to a scope in your function, you should use a local std::unique_ptr<> to manage the dynamic memory, and ensure it is released no matter how you leave the scope: by return, throw, break etc.. (You may also use a std::unique_ptr<> data member in a class/struct to manage any memory the object owns.)

Mathieu Van Nevel comments below about C++11 move semantics - the relevance is that if you have a small management object on the stack that controls a large amount of dynamically allocated (heap) memory, move semantics grant extra assurances and fine-grained control of when the management object hands over its resources to another management object owned by other code (often the caller, but potentially some other container/register of objects). This handover can avoid data on the heap being copied/duplicated even momentarily. Additionally, elision and return-value-optimisation often allow nominally automatic/stack-hosted variables to be constructed directly in some memory they're eventually being assigned/returned-to, rather than copied there later.

这篇关于C ++堆栈与堆分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆