【问题标题】:Can I use blocks to manage memory consumtion in C++?我可以使用块来管理 C++ 中的内存消耗吗?
【发布时间】:2010-10-09 12:40:03
【问题描述】:

我正在尝试在 C++ 程序中节省一些内存,我想知道是否可以将块用作变量的范围(如在 Perl 中)。假设我有一个执行一些计算并给出结果的 巨大 对象,这样做是否有意义:

InputType  input;
ResultType result;

{
    // Block of code
    MyHugeObject mho;
    result = mho.superHeavyProcessing();
}

/*
   My other code ...
*/

我可以期望对象在退出块时被销毁吗?

【问题讨论】:

    标签: c++ object scoping


    【解决方案1】:

    是的,你可以。

    一旦变量超出范围,析构函数就会被调用,它应该释放堆分配的内存。

    【讨论】:

    • 严格来说,调用析构函数并不等同于释放用于对象存储的内存。
    • 我认为可以安全地假设问题中的 huge 词意味着对象已在堆上分配了较大的内存块并希望将其释放(例如向量)。
    • 对不起,但我似乎认为 MyHugeObject 是在堆栈上分配的,而不是在堆上分配的,除非完成了明确的 malloc。如果我错了,请纠正我。
    • @user247077 MyHugeObject 实例本身肯定存在于堆栈中。不过,这不是我要说的。让我澄清一下。考虑到堆栈空间通常是有限的,并且大多数时候您不会在堆栈上分配大量内存,MyHugeObject 类可能会在初始化时在堆上分配一个成员。无论如何,堆栈分配的内存也会在函数结束时释放。
    【解决方案2】:

    绝对是的,除了节省内存之外,在范围退出时调用析构函数通常用于您希望析构函数在调用析构函数时实际执行某些操作(请参阅 RAII)。例如,创建一个基于作用域的锁并以异常安全的方式轻松释放它,或者确定性地放弃对共享或宝贵资源(如文件句柄/数据库连接)的访问。

    -瑞克

    【讨论】:

    • +1 用于引用基于范围的锁定,一个非常好的概念。
    【解决方案3】:

    请记住,您使用在析构函数中释放的 new/malloc 在堆上分配的任何内存可能不会被释放回操作系统。您的进程可能会保留它,并且操作系统在进程终止之前不会将其取回。

    【讨论】:

    • 尽管在这种情况下内存在堆栈上,操作系统可能已经将其提交给您的程序。 (尽管在 Windows 上,令人惊讶的是并非总是如此!)
    • 是的——我的假设是任何对象巨大的对象都必须在内部动态分配内存,即使它在堆栈本身上。
    • 这并不准确。虽然大块内存仍将分配给应用程序,但如果它未使用,它将被分页出物理内存,不会以任何方式影响性能。一些操作系统(Windows)管理未使用的分页内存有点弱,但这总是可以通过使用内存映射文件并在完成后取消映射来规避,因为这实际上为该地址空间创建了一个单独的页面文件。
    【解决方案4】:

    是的。它将在右花括号处被破坏。但要注意在堆栈上分配非常大的对象。这会导致堆栈溢出。如果您的对象还分配大量内存,请确保它是使用 new、malloc 或类似方法分配的堆。

    【讨论】:

    • 对象实际上指向堆分配的内存,但我想尽快释放它。
    猜你喜欢
    • 1970-01-01
    • 2016-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    • 2013-07-09
    • 2012-03-15
    • 1970-01-01
    相关资源
    最近更新 更多