Are memory leaks "undefined behavior" class problem in C++?
Solution 1:
Memory leaks.
There is no undefined behavior. It is perfectly legal to leak memory.
Undefined behavior: is actions the standard specifically does not want to define and leaves upto the implementation so that it is flexible to perform certain types of optimizations without breaking the standard.
Memory management is well defined.
If you dynamically allocate memory and don't release it. Then the memory remains the property of the application to manage as it sees fit. The fact that you have lost all references to that portion of memory is neither here nor there.
Of course if you continue to leak then you will eventually run out of available memory and the application will start to throw bad_alloc exceptions. But that is another issue.
Solution 2:
Memory leaks are definitely defined in C/C++.
If I do:
int *a = new int[10];
followed by
a = new int[10];
I'm definitely leaking memory as there is no way to access the 1st allocated array and this memory is not automatically freed as GC is not supported.
But the consequences of this leak are unpredictable and will vary from application to application and from machine to machine for a same given application. Say an application that crashes out due to leaking on one machine might work just fine on another machine with more RAM. Also for a given application on a given machine the crash due to leak can appear at different times during the run.
Solution 3:
If you leak memory, execution proceeds as if nothing happens. This is defined behavior.
Down the track, you may find that a call to malloc
fails due to there not being enough available memory. But this is a defined behavior of malloc
, and the consequences are also well-defined: the malloc
call returns NULL
.
Now this may cause a program that doesn't check the result of malloc
to fail with a segmentation violation. But that undefined behavior is (from the POV of the language specs) due to the program dereferencing an invalid pointer, not the earlier memory leak or the failed malloc
call.
Solution 4:
My interpretation of this statement:
For an object of a class type with a non-trivial destructor, the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released; however, if there is no explicit call to the destructor or if a delete-expression (5.3.5) is not used to release the storage, the destructor shall not be implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior.
is as follows:
If you somehow manage to free the storage which the object occupies without calling the destructor on the object that occupied the memory, UB is the consequence, if the destructor is non-trivial and has side-effects.
If new
allocates with malloc
, the raw storage could be released with free()
, the destructor would not run, and UB would result. Or if a pointer is cast to an unrelated type and deleted, the memory is freed, but the wrong destructor runs, UB.
This is not the same as an omitted delete
, where the underlying memory is not freed. Omitting delete
is not UB.