问题
All good C++ programmers know how to avoid leaking memory (or resources like sockets):
- Always use smart pointers, i. e.:
std::auto_ptr,boost::shared_ptr. - Always be aware of ownership of object: who owns, who refers, who is responsible, etc.
But, memory leaks still happen. Point most common issues when you discovered a memory leak in a program, even when you used the above techniques.
I start:
Sometimes you forget to define a destructor of base class as virtual. So all derived classes referred by pointer to the base class which was not destroyed properly and therefore leaked.
回答1:
There are many more types of errors than just leaks. In order from worst to best:
Memory corruption.
Data is stored to an area where it shouldn't. This results in both the majority of security problems and is by far the hardest to track down.
- "Random location" corruption
- Data is stored to a memory location that the user can control.
- Data is stored to an array without checking the indices.
- An object of a type derived from
Xis stored to an array element reserved for a base type ofX, and the size ofXis greater than the size of its base.
- Lifetime corruption
- Data is store to a memory location after it is freed.
- Incorrect method of freeing is used (mismatch resulting in
new/free,malloc/delete) deleteorfreeis called twice on the same pointer.
Failure to release memory
Memory no longer in use by the program remains allocated.
- Incorrect method of freeing is used: mismatch resulting in
new[]/deleteinstead ofnew[]/delete[]. - Memory is not automatically release because of a circular reference in a reference counting scheme, such as can happen when
smart_ptris used in a circular data structure without attention to usingweak_ptrfor the circular link. - Memory is not freed due to a lost pointer - the last pointer to the memory was cleared before free was called, so there is no way to release it.
- Memory is not freed due to not properly identifying when the data it contains is no longer needed. An example is a static cache used for some temporary task is never cleared out.
回答2:
Circular references are common, and they aren't solved by std::auto_ptr or boost::shared_ptr
There is no substitute for (2) on your list, which is using your brain.
回答3:
- Calling a virtual function like "cleanup" from within the base-class destructor. You probably only do this once... (no more polymorphism in the destructor of the base-class)
- Not cleaning up an stl::multimap (no erasing, only inserting) and wondering why your program keeps on becoming slower.
回答4:
A mistake made by people too familiar with automatic garbage collection (through smartpointers):
class A {
public:
int avery_useful_calculation()const { return 4; }
private:
// class shouldn't be instantiated as an automatic variable (on stack)
virtual ~A(){}
};
// client code: needs a very useful calculation
int i = (new A)->avery_useful_calculation();
回答5:
Maybe I am out of scope, but I had some strange errors trying to "delete" uninitialized pointers.
To "avoid" memory leakage, I use the try {} __finally {} structure if implemented (but I read somewhere it may be inefficient if an exception was raised in a sub-sub-call)
来源:https://stackoverflow.com/questions/1332670/most-common-memory-resource-leak-errors