I can't understand the end of this code (array = 0;
):
#include <iostream>
int main()
{
std::cout << "Enter a positive integer: ";
int length;
std::cin >> length;
int *array = new int[length];
std::cout << "I just allocated an array of integers of length " << length << '\n';
array[0] = 5; // set element 0 to value 5
delete[] array; // use array delete to deallocate array
array = 0; // use nullptr instead of 0 in C++11
return 0;
}
At the end, a dynamically allocated array is deleted (returned to OS) and then assigned a value of 0.
Why is this done? After array has been returned to the OS, there is no need to assign it a value of 0, right?
Code from: http://www.learncpp.com/cpp-tutorial/6-9a-dynamically-allocating-arrays/
For dynamically allocated memory like “int *p = new int[10]”, it is programmers responsibility to deallocate memory when no longer needed. If programmer doesn't deallocate memory, it causes memory leak (memory is not deallocated until program terminates).
The C++ keyword delete is used to release dynamically allocated memory so that it may be reused.
For dynamically allocated memory like “int *p = new int[10]”, it is the programmer's responsibility to deallocate memory when no longer needed. If the programmer doesn't deallocate memory, it causes a memory leak (memory is not deallocated until the program terminates).
Dynamically allocated memory must be referred to by pointers. the computer memory which can be accessed by the identifier (the name of the variable). integer, 8, stored. The other is the “value” or address of the memory location.
After array has been returned to the OS, there is no need to assign it a value of 0, right?
You're right it is not needed because the memory is freed (deallocated) by the operator delete
. But think of a case where you may use the pointer in another place in your code (functions, loops, etc.) after you use delete[]
on it.
The array
variable still holds the address of the old allocation after the delete[]
statement was called (dangling pointer). If you would access that address you would get undefined bahaviour (UB) because the memory is no longer yours, in most of the cases your program would crash.
To avoid that you do a null pointer check like:
if (array != nullptr)
{
/* access array */
...
}
which is checking the pointer against the address 0 which represents an invalid address.
To make that check possible you set the pointer to nullptr
or NULL
if C++11 is not available. The nullptr
keyword introduces type safety because it acts like a pointer type and should be preferred over the C-like NULL
. In pre C++11 NULL
is defined as integer 0, since C++11 it's an alias to nullptr
.
To define your own nullptr
to use it for pre C++11 compiler look here: How to define our own nullptr in c++98?
An interesting fact about delete
or delete[]
is that it is safe to use it on a nullptr
. It is written at point 2 on cppreference.com or at this SO answer.
operator delete, operator delete[]
2) [...] The behavior of the standard library implementation of this function is undefined unless
ptr
is a null pointer or is a pointer previously obtained from the standard library implementation ofoperator new[](size_t)
or operatornew[](size_t, std::nothrow_t)
.
We are setting pointers to NULL
(0) to avoid dangling pointers (pointer is still pointing to same memory which is no longer yours). In case of local variables it is not that useful if function doesnt continue after delete (so its obvious pointer won't be reused). In case of global/member poitners its good practice to avoid bugs.
Accessing already deleted pointer may lead to overwriting/reading random memory (it might be more dangerous than crash) and causes undefined behavior, while accessing NULL
pointer will immediatelly crash.
Since c++11 you should use nullptr
because its defined as pointer type while NULL
is more int
type and improves type safety + resolves ambiguous situations.
In case of double deleting pointer, its safe to use delete on nullptr
and nothing happens but if you delete already deleted non-null pointer, it will cause undefined behavior and most likely program will crash.
In c++ you should avoid using pure pointers since there are STL containers (which frees their resources them self (RAII)) for this usage or smart pointers.
std::vector<int> array{1,2,3,4,5};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With