C ++ memory leak example (using exceptions)

In C ++, How to Program There is a paragraph that says:

The general programming practice is to allocate dynamic memory, assign the address of this memory to a pointer, use the pointer to manage the memory and free the memory with deletion when the memory is no longer needed. If an exception occurs after a successful memory allocation, but before the delete statement is executed, a memory leak may occur. The C ++ standard provides a unique_ptr template template in the header to handle this situation.

Any on can provide me with a real example that an exception is occurring and memory is flowing like this post ?

+4
source share
5 answers
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); } 

See also: C ++: handle resources if constructors can throw exceptions (link to frequently asked questions 17.4)

+5
source

A bit more subtle example.

Take a naive implementation of a class that contains two dynamically allocated arrays:

 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 */ } 

Now, if we get an exception, because we call the Bar method somewhere, everything is fine - the confirmation that the stack is freed is called by the destructor f .

But if we get a bad_alloc when initializing second , we will skip the memory pointed to by first .

+8
source
 void func() { char *p = new char[10]; some_function_which_may_throw(p); delete [] p; } 

If the call some_function_which_may_throw(p) throws an exception, we leak the memory pointed to by p .

+6
source

Simple example

 try { int* pValue = new int(); if (someCondition) { throw 42; } delete pValue; } catch (int&) { } 
+3
source

To have a less contrived example, I recently discovered this potential leak in my code when allocating nodes with a given allocator object.

 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 } 

It is less obvious how to fix this due to the buffer, but with the help I got it:

 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)); } 

Code compilation here

+1
source

All Articles