作者热门文章
- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
所以我有一个看起来像这样的基类:
class base {
public:
base() {
std::cout << "We created a base!" << std::endl;
}
~base() {
std::cout << "We destroyed a base!" << std::endl;
}
};
我有一个派生类,如下所示:
class leaks_memory : public base {
public:
leaks_memory(size_t count) :
memory(new int[count]), size_of_memory(count)
{
announce();
}
leaks_memory(const leaks_memory & lm) :
leaks_memory(lm.size_of_memory)
{
std::copy(lm.memory, lm.memory + size_of_memory, memory);
}
void swap(leaks_memory & lm) noexcept {
std::swap(lm.memory, memory);
std::swap(lm.size_of_memory, size_of_memory);
}
leaks_memory(leaks_memory && lm) {
swap(lm);
}
leaks_memory & operator=(leaks_memory lm) {
swap(lm);
return *this;
}
~leaks_memory() {
delete[] memory;
dennounce();
}
int & operator[](size_t index) {
return memory[index];
}
const int & operator[](size_t index) const {
return memory[index];
}
private:
int * memory;
size_t size_of_memory;
void announce() const noexcept {
std::cout << "We created a Leaks Memory!" << std::endl;
}
void dennounce() const noexcept {
std::cout << "We destroyed a Leaks Memory!" << std::endl;
}
};
现在,就其本身而言,这些都不是问题,直到我编写如下所示的代码:
int main() {
std::unique_ptr<base> base_ptr;
std::atomic_bool done = false;
std::thread input_thread{ [&done] {
std::getline(std::cin, std::string());
done = true;
} };
while (!done) {
base_ptr = std::make_unique<leaks_memory>(20'000);
}
input_thread.join();
return 0;
}
此代码在循环的每次迭代中泄漏 20kb,因为永远不会调用 leaks_memory
析构函数!
现在,显然,我可以通过对 base
进行编辑来解决这个问题:
virtual ~base() {
std::cout << "We destroyed a base!" << std::endl;
}
事实上,如果我在进行此更改后运行相同的代码,我将不再有此内存泄漏。
但是,如果我处于无法编辑 base
类的情况怎么办?有没有办法在不完全改变执行代码的设计的情况下防止内存泄漏?
最佳答案
C++11 智能指针具有自定义删除器,这在一定程度上放宽了在每个层次结构的根部具有虚拟析构元的要求。
不幸的是这个特性并不好用,因为删除器的类型是shared_ptr和unique_ptr的模板参数。所以为了隐藏最终对象的类型,需要一些类型删除:
void derived_deleter(base* p) { delete static_cast<derived*>(p); }
std::unique_ptr<base, decltype(&derived_deleter)> base_ptr (new derived, derived_deleter);
好像没有办法使用std::make_unique。
关于c++ - 有没有办法在不修改基类的情况下防止派生类中的内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37009057/
我是一名优秀的程序员,十分优秀!