C ++块代码在功能完成之前保存内存?

时间:2013-10-13 20:35:47

标签: c++ garbage-collection

由于我有更多的Java经验,而且我现在正在深入C ++世界,我在Java中知道一些我不确定它是否像在C ++上一样工作。

实际上我得到了这个伪C ++代码:

unsigned long __stdcall MyFunction()
   {
    //Do some code that will take a while to complete...

       {
            MY_BIG_STRUCT mbStruct = {};
            mbStruct.a = "a";
            [...];
            UseMyStructData(&mbStruct);
        }

    //Do some code that will take a while to complete...

    return EXIT_SUCCESS;
}

所以我的问题是:在JAVA上使用括号{}中的那些代码块将标记为“自由”的那些变量到GC释放它们,即使该函数没有完成它的执行。那么,在C ++上,这可以用同样的方式工作吗?或者如果我没有块语句(如if,while,switch等等),使用{}是无用的?

致以最诚挚的问候,

Afonso Lage。

4 个答案:

答案 0 :(得分:2)

非托管C ++中没有GC。 mbStruct的析构函数将在}括号的末尾调用,但是因为它是堆栈上的变量(而不是在new的堆上)。 { }创建一个范围,使得在结束范围括号中调用析构函数。即使从函数中抛出异常,析构函数也能保证运行。

此外,C ++采用“确定性破坏”,这意味着您可以保证析构函数将同步运行(在结束}),而不是具有GC的系统,其中对象在GC内存管理器的自由裁量权。

答案 1 :(得分:1)

将在堆栈上分配的自动变量被释放。这与Java中的垃圾收集器不同,因为它是自动堆栈分配,而不是堆分配。在使用方面,它看起来与你一样。

如果您从堆中分配了某些内容(使用new / malloc) - 您必须自行取消分配(使用delete / free)。请使用unique_ptrshared_ptr

答案 2 :(得分:1)

C ++中没有GC。但是,垃圾收集器只处理动态分配的内存。这是newmalloc()。当范围退出时,自动变量将被销毁。 mbStruct是一个自动变量,因此当它超出范围时会被销毁。

此外,除非您需要精细控制,否则不需要显式{ }范围。另请注意,范围在结束}之前结束。例如:

void foo()
{
    SomeClass someObj;
    if (some_condition) {
        return;
    }
}
即使someObj为真且some_condition已执行,

return也会被销毁;离开范围与结束范围具有相同的效果。

您应该注意不要将指针(或引用)保留在超出范围的变量中。例如,这会爆炸:

void foo()
{
    SomeClass* someObj_ptr;

    {
        SomeClass someObj;
        someObj_ptr = &someObj;
    }
    someObj_ptr->function(); // Mistake: someObj no longer exists.
}

内部范围结束后,someObj已被销毁但someObj_ptr仍然引用它。在其上调用function()(假设SomeClass具有此类成员函数)是错误的。请注意,编译器无法捕获该错误。你必须意识到这一点,并且永远不要保持对超出范围的变量的指针或引用。与Java相反,在C ++中,变量不是引用计数,如果有引用则不会保持活动状态。如果变量超出范围,它就会消失,无论其他变量是否仍然引用它们。

答案 3 :(得分:0)

在C ++中以相同的方式工作。您的MY_BIG_STRUCT将在阻止结束时发布。