C ++内存耗尽

时间:2012-02-09 06:44:15

标签: c++ memory garbage

我一直在教自己C ++,有人告诉我C ++没有垃圾收集器。现在我不确定这意味着什么程度。

假设我有这段代码:

double multiply (double a, double b) {
    double result = a * b;
    return result;
};
int main (char* args[]) {
    double num1 = 3;
    double num2 = 12;
    double result = multiply(num1, num2);
    return 0;
}

multiply方法包含内部变量“result”。现在是仍然分配和/或锁定变量“result”的内存地址?参数“a”和& “B”?

6 个答案:

答案 0 :(得分:5)

标准C ++根本没有垃圾收集器。

但自动变量(“堆栈”变量)在其作用域结束时被清除,在必要时调用析构函数。 (示例中的所有变量都是自动的。)

您需要担心的是动态分配:您通过new运算符创建的任何内容。那些没有自动清理 - 你需要delete他们或他们会泄漏。 (或使用智能指针。)

答案 1 :(得分:2)

您提到的所有变量都在堆栈中。一旦它们离开示波器,内存就会自动释放。

答案 2 :(得分:2)

垃圾收集意味着您的垃圾(上不可访问/引用的内存)将自动释放。本地内存/变量(局部变量)将不会被分配,而是被推送到堆栈,并且如果您将块保留在定义var的位置,则会自动释放。

所以,如果你使用你的代码,你就没事了。但是如果你使用

double multiply (double a, double b) {
    double *result = new double;
    *result = a * b;
    return *result;
};

然后result中的内存仍然被分配,'锁定'并丢失。另请参阅http://en.wikipedia.org/wiki/Call_stackhttp://en.wikipedia.org/wiki/Dynamic_memory_allocation#Dynamic_memory_allocation

答案 3 :(得分:1)

实际上,C ++是一个非常好的资源管理!它不会对堆上分配的对象执行垃圾收集。合理地说,您没有在堆上分配任何内容,并且在许多情况下,当您执行此操作时,您可能不会明确地执行此操作(例如,在使用std::vector<T>时)。要获得由其他语言的垃圾收集处理的资源泄漏,使用new在堆上分配对象:您需要将每个内存分配(实际上,任何资源分配)与相应的版本配对。使用像std::vector<T>std::shared_ptr<T>之类的东西来处理C ++中的大量资源泄漏。

也就是说,您的示例程序没有资源泄漏。

答案 4 :(得分:1)

C ++有两种主要的内存类型,分配对象:堆栈和免费存储(堆)。堆栈上的对象被手动分配和释放,这些对象包括函数参数,自动(本地)变量,临时对象,返回值。而是通过newnew[]deletedelete[]明确管理免费商店(堆)上的对象。您还可以使用malloc / free或使用花哨的命名函数operator newoperator delete及其[]对应文件,从免费商店管理原始内存。

对于在C ++中的免费商店管理的对象,程序员有责任负责分配和解除分配...在其他语言中,这是自动的。 在C ++中,您还需要注意基于堆栈的对象的生命周期绑定到范围(例如,存储或返回局部变量的地址是常见错误,或许多错误),这也是一个非问题用其他语言。

这种复杂化的主要原因是速度:使用基于堆栈的分配逻辑比使用免费存储更快(当前处理器在堆栈上分配许多变量只需要一次添加,并且只需要减去它们就可以解除分配)。 / p>

使用其他语言,编译器会分析代码并决定可以使用堆栈分配的位置以及不能使用的位置,而在C ++中这是程序员的工作。

请注意,在C ++中,内存管理实际上比这个解释更复杂(例如,还有存储异常对象的内存,可以有类的自定义分配器,并且容器有allocator参数)但是程序员很少需要考虑它。

答案 5 :(得分:0)

(主要是忽略外部库)确实C ++没有垃圾收集器。相反,它具有自动存储持续时间的概念。

范围内的对象具有由该范围分隔的生命周期,在您的示例中,resultmultiply内构建,然后result的副本返回到{{ 1}},再次将其复制到main中的main

result范围的末尾,multiply被销毁,并且释放了result的内存。

这个&#34;自动内存管理&#34;不使用垃圾收集器,它完全是确定性的。