[英]Example of memory leak in c++ (by use of exceptions)
一个更微妙的例子。
对包含两个动态分配的数组的类进行简单的实现:
struct Foo {
private:
int* first;
int* second;
public:
Foo()
: first(new int[10000])
, second(new int[10000])
{ }
void Bar() { throw 42; }
~Foo()
{
delete [] first;
delete [] second;
}
};
int main()
{
Foo f;
/* more code */
}
现在,如果我们得到一个异常,因为我们在某处调用方法Bar
,一切都很好 - 堆栈展开保证f
的析构函数被调用。
但是如果我们在初始化second
时得到bad_alloc
,我们会泄漏first
指向的内存。
void func()
{
char *p = new char[10];
some_function_which_may_throw(p);
delete [] p;
}
如果对some_function_which_may_throw(p)
的调用抛出异常,则会泄漏p
指向的内存。
class MyClass
{
public:
char* buffer;
MyClass(bool throwException)
{
buffer = new char[1024];
if(throwException)
throw std::runtime_error("MyClass::MyClass() failed");
}
~MyClass()
{
delete[] buffer;
}
};
int main()
{
// Memory leak, if an exception is thrown before a delete
MyClass* ptr = new MyClass(false);
throw std::runtime_error("<any error>");
delete ptr;
}
int main()
{
// Memory leak due to a missing call to MyClass()::~MyClass()
// in case MyClass()::MyClass() throws an exception.
MyClass instance = MyClass(true);
}
简单的例子
try {
int* pValue = new int();
if (someCondition) {
throw 42;
}
delete pValue;
} catch (int&) {
}
为了得到一个不那么人为的例子,我最近在分配具有给定分配器对象的节点时发现了我的代码中的潜在泄漏。
std::unique_ptr<node,alloc_aware> allocate_new_node(allocator& al, const value_type^ v) {
char* buffer = al.allocate(sizeof(node)); //allocate memory
return std::unique_ptr<node>(al.construct(buffer, v),{al})); //construct
}
由于缓冲区,如何解决这个问题的方法不太明显,但在我得到它的帮助下:
struct only_deallocate {
allocator* a;
size_type s;
only_deallocate(allocator& alloc, size_type size):a(&alloc), s(size) {}
template<class T> void operator()(T* ptr) {a->deallocate(ptr, s);}
operator alloc_aware() const {return alloc_aware(*a, s);}
};
std::unique_ptr<node,alloc_aware> allocate_new_node(allocator& al, const value_type& v) {
std::unique_ptr<node, only_deallocate> buf(alloc.allocate(sizeof(node)),{alloc, sizeof(node)});//allocate memory
alloc.construct(buf.get(), value);
return std::unique_ptr<node,alloc_aware>(std::move(buf));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.