dilipIsharaonline
dilipIsharaonline

Reputation: 49

Is it valid to assign a new memory block to a variable with a deleted pointer?

int main(){
    char *Allocation;
    Allocation = new char[8]; //here is out first allocation;

    delete[] Allocation;      //after while we delete it;
    
    Allocation = new char[16];//then we allocate some chunk of memory again to our pointer;

    delete[] Allocation;      //then finally we delete our second allocation;
}

Is this valid in C++? Does the first allocation affect the second allocation? Can I allocate a new memory block to a deleted pointer?

Upvotes: 2

Views: 103

Answers (2)

NIKHIL UPADHYAY
NIKHIL UPADHYAY

Reputation: 11

In cpp,it is completely valid to assign a new memory block to a deleted pointer. Second allocation does not get affected by the previously assigned memory block. We manage memory allocations and deallocations properly so as to avoid memory leaks and undefined behavior.

Upvotes: 1

Benjamin Buch
Benjamin Buch

Reputation: 6123

tl;dr Yes, that's perfectly fine.

You have to distinguish between the actual value in memory and the value of the pointer variable that points to this actual value in memory.

new provides the actual value in memory (which is not bound to a variable) and returns its address. This returned address is then set by assignment as the value of the variable Allocation.

With delete you remove the actual value from memory. But this usually does not affect the value of the variable Allocation. The address is therefore retained, but must no longer be dereferenced. It is undefined what happens if you do this anyway.

Therefore it is recommended to assign a nullptr (null pointer) to Allocation right after calling delete. Some implementations do assign a nullptr implicitly after delete if the program is compiled in debug mode. Therefore the usually above.

A nullptr is just the address with the value 0. An access on this address is always invalid, so its the common value to imply that a pointer doesn't point to a valid location.

So you can assign a different address as value to the variable Allocation at any time. The memory managed with new and delete exists independent of variables. These are only used for access.


By the way, you should initialize your variable Allocation with either a call to new or with a nullptr. Otherwise your variable Allocation may contain some random value

#include <iostream>

int main() {
    char* a = new char[8]; // contains address of valid value
    // or
    char* b = nullptr; // contains address to "nowhere"
    char* c{nullptr};  // also fine
    char* d(nullptr);  // also fine
    char* e{};         // also fine (implicit nullptr)

    // Bad:
    char* f; // may contain any address

    std::cout << std::hex
        << "a: " << reinterpret_cast<std::size_t>(a) << '\n'
        << "b: " << reinterpret_cast<std::size_t>(b) << '\n'
        << "c: " << reinterpret_cast<std::size_t>(c) << '\n'
        << "d: " << reinterpret_cast<std::size_t>(d) << '\n'
        << "e: " << reinterpret_cast<std::size_t>(e) << '\n'
        << "f: " << reinterpret_cast<std::size_t>(f) << '\n';

    // Note: C++ syntax is evil 👿
    char* g(); // function declaration, e{} was a variable definition
    char* h(std::nullptr_t); // also a function declaration, compare to d
                             // nullptr is a value
                             // std::nullptr_t is a type

    // Linker error: undefined reference to `g()'
    // std::cout << reinterpret_cast<std::size_t>(g) << '\n';

    delete[] a;
}

Live code at Compiler Explorer

Output:

a: 558bb9976eb0 (possible output, always a valid address value)
b: 0
c: 0
d: 0
e: 0
f: 3a66 (possible output, may have any address value)

Note that C++ distinguishes between initialization and assignment:

char* Allocation = new char[8]; // initialization 
Allocation = new char[8];       // assignment

Upvotes: 3

Related Questions