【发布时间】:2021-06-13 13:08:04
【问题描述】:
(在有人问之前:否,我没有忘记 delete[] 语句)
我在摆弄动态分配的内存时遇到了这个问题。我认为解释它的最好方法是向您展示我编写的这两段代码。它们非常相似,但其中一个没有调用我的类析构函数。
// memleak.cpp
#include <vector>
using namespace std;
class Leak {
vector<int*> list;
public:
void init() {
for (int i = 0; i < 10; i++) {
list.push_back(new int[2] {i, i});
}
}
Leak() = default;
~Leak() {
for (auto &i : list) {
delete[] i;
}
}
};
int main() {
Leak leak;
while (true) {
// I tried explicitly calling the destructor as well,
// but this somehow causes the same memory to be deleted twice
// and segfaults
// leak.~Leak();
leak = Leak();
leak.init();
}
}
// noleak.cpp
#include <vector>
using namespace std;
class Leak {
vector<int*> list;
public:
Leak() {
for (int i = 0; i < 10; i++) {
list.push_back(new int[2] {i, i});
}
};
~Leak() {
for (auto &i : list) {
delete[] i;
}
}
};
int main() {
Leak leak;
while (true) {
leak = Leak();
}
}
我使用g++ filename.cpp --std=c++14 && ./a.out 编译它们并使用top 检查内存使用情况。
如您所见,唯一的区别是,在memleak.cpp 中,类构造函数不做任何事情,并且有一个 init() 函数来完成它的工作。但是,如果您尝试一下,您会发现这会以某种方式干扰被调用的析构函数并导致内存泄漏。
我是否遗漏了一些明显的东西?提前致谢。
另外,在有人建议不要使用动态分配的内存之前:我知道这并不总是一个好的做法等等,但我现在感兴趣的主要事情是了解为什么我的代码不能正常工作预计。
【问题讨论】:
-
你怎么知道析构函数被调用/没有被调用?
-
@largest_prime_is_463035818 我只是在代码中添加了一些 printf 语句
-
为什么在这里发帖时删除它们?您的问题实际上是关于您的代码的一些输出,但是您在此处发布的代码中没有输出
-
@largest_prime_is_463035818 我删除它们只是为了使代码更易于阅读。正如我所说,您只需运行
top并查看内存使用情况即可看到存在问题