Are Memory Leaks "Undefined Behavior" Class Problem in C++

Are memory leaks undefined behavior class problem in C++?

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.

Can free() cause a memory leak?

Can that cause a memory leak?

In your particular example, no. The x object is merely being allocated by malloc(). free() will correctly deallocate the memory that malloc() allocated. But the object will not be destructed, which is fine in this example because it was not constructed to begin with, so there is nothing to destruct. However, if you try to use that object in any way that expects the constructor to have run, then you end up in undefined behavior territory.

C (where malloc() and free() come from) has no concept of classes, only of memory (de)allocation. C++, on the other hand, has separate concepts of memory (de)allocation and object (de)construction, so you need to be very careful that you use them correctly and not mix them up incorrectly.

If an object were constructed via new, but then deallocated by free() rather than being destructed by delete, the code would definitely have undefined behavior, and if that object had internally allocated any additional memory for itself that the object's destructor is expected to free, that extra memory would be leaked, yes.

new() without delete() is Undefined Behavior or merely Memory Leak?

[basic.life] (3.8 Object lifetime) in paragraph 4 tells :

A program may end the lifetime of any object by reusing the storage which the object occupies or by explicitly calling the destructor for an object of a class type with a non-trivial destructor. 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.

I can't understand how to solve problem with memory leak C++

I wouldn't call it a leak, but you treat end_ inconsistently. It seems like you are treating Size and Capacity as equivalent values, they are not.

Either end_ should point one past the allocated (but not necessarily populated) memory, and you return data + size in end(), or it should point one past the last element, and you should store size_t capacity_ not size_t size_;

Does this C++ Class Leak Memory?

You should not use malloc and free unless you interface with C code. Try to avoid new and delete as well, since C++ has many simpler patterns that are guaranteed not to leak and are as fast. Think of std::vector and, if vector is not good enough, think of std::unique_ptr<int[]> narr with std::make_unique<int[]>(size).

Your program does not leak and does not crash by pure luck. To avoid leaks your class should have a clear invariant regarding memory, and it has none. There is no way to know when narr has an invalid pointer, or when it points to memory that has to be freed. As a result the following leaks:

int arr1[size] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
BubbleSort sort = BubbleSort::BubbleSort(size, arr1);
int* narr = sort.Sort();
narr = sort.Sort();

And the following has undefined behavior (free over an uninitialized pointer):

int arr1[size] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
BubbleSort sort = BubbleSort::BubbleSort(size, arr1);
return 0;

The easiest way (and correct in 99.9% of the cases) to deal with this, is to define ownership. You decide up-front who owns what object. With std::vector and std::unique_ptr the language decides it for you. The language does not let you accidentally transfer ownership of std::unique_ptr without an explicit action on your part. If you make a mistake, the compiler will simply give you an error.


Side note: if you want to learn C++, when you come from C background, it might be easier to start with malloc, free, printf, and raw pointers everywhere. However, you should remember that this is not idiomatic C++. Sooner or later you must move to C++ idioms like RAII, classes that have clear ownership and invariant, and use C++ library instead of C.

Does this code cause memory leak?

It not only leaks the dynamically allocated int but also has undefined behaviour, because you can't delete an object that wasn't allocated with new (§5.3.5/2).

the value of the operand of delete may be a null pointer value, a pointer to a non-array object created by a previous new-expression, or a pointer to a subobject (1.8) representing a base class of such an object (Clause 10). If not, the behavior is undefined.

Since the object denoted by y was not allocated with a new-expression, you cannot use delete to destroy it. Its lifetime is governed by its scope.



Related Topics



Leave a reply



Submit