我是该语言的新手,我对内存泄漏有基本的疑问。
如果我不使用new
关键字,可能会泄漏吗? (即,将我的变量放在堆栈中,并使用std::vector
之类的数据容器)
我应该担心这个问题吗?
如果是这种情况,有人可以给我举个例子说明在没有动态分配内存的情况下造成泄漏的情况吗?
答案 0 :(得分:7)
即将我的变量放在堆栈中,并使用
std::vector
等数据容器
否,使用std::vector
或其他标准容器,您不必担心。
有人可以给我举一个情况的例子吗?这种情况会在不动态分配内存的情况下造成泄漏?
一个常见的错误是以下形式的循环依赖型智能指针:
class Child;
class Parent {
std::vector<std::shared_ptr<Child>> childs;
};
class Child {
std::shared_ptr<Parent> parent;
};
由于共享指针的引用计数器永远不会降为零,因此这些实例将永远不会被删除并导致内存泄漏。
有关导致该问题的原因以及如何避免它的更多信息,请点击此处
答案 1 :(得分:4)
如果您不动态保留内存,我认为不可能泄漏内存。可能不会释放全局变量,但我不会称之为内存泄漏。
但是,与使用关键字new
相比,动态保留内存的方法更多。
例如,malloc
分配一个内存块。 calloc
还会保留内存并将其清零。
您的操作也可以为您提供管理内存的方法。例如strdup
(对于Linux)。
您还可以使用智能指针并调用std::make_unique
或std::make_shared
。两种方法都动态分配内存。
对于std::unique_ptr
,如果调用release()
可能会泄漏而忘记删除指针。
std::make_unique<int>(3).release(); // Memory leak
对于std::shared_ptr
,如果您创建循环引用,则可能会泄漏。您可以找到更多信息here。
此外,当您使用静态变量时,在变量超出范围时而是在执行结束时不调用析构函数。这并不是完全的内存泄漏,因为析构函数最终被调用了,但是您可能已经分配了一些内存而未使用它们。
例如,考虑以下代码:
#include <iostream>
#include <string>
#include <vector>
void f()
{
static std::vector<int> v;
v.insert(v.begin(), 100*1024*1024, 0);
v.clear();
}
int main()
{
f();
return 0;
}
不需要 std::vector::clear()
来释放向量分配的内存。因此,在调用f()
之后,您将分配400 MB的内存,但只能在f()
内部访问。不完全是内存泄漏,它是分配的资源,直到结束时才自动释放。
答案 2 :(得分:4)
除了其他答案,内存泄漏的一个简单来源是外部库。它们中的许多,尤其是C或类似C的库,其数据类型都具有类似create_*
和destroy_*
的功能。即使您从未显式调用new
,也很容易发生内存泄漏。