Language: EN

cpp-new-y-delete

What are new and delete in C++

To manage dynamic memory, C++ provides two operators new and delete to allocate and deallocate memory, respectively.

In C++, memory can be managed in two main ways:

  • Automatic memory: It is automatically allocated when a local or global variable is declared and is automatically freed when the variable goes out of scope.

  • Dynamic memory: It is manually allocated and deallocated by the programmer during the execution of the program using the new and delete operators.

Basically, dynamic memory is storage space that we need, but we do not know how much we need until runtime (for example, because it depends on a system input).

Unlike automatic memory, memory allocated with new persists until it is explicitly freed with delete.

What is new

The new operator in C++ is used to allocate dynamic memory (i.e., to tell the system “hey!, give me a place to store this”).

data_type* pointer = new data_type;
  • data_type: This is the data type for which memory is being allocated.
  • pointer: This is a pointer that will store the address of the allocated memory.

Let’s see it with an example,

int* p = new int; // Allocates memory for an integer
*p = 5;           // Stores the value 5 in the allocated memory

std::cout << *p << std::endl; // Prints 5

In this example,

  • Memory is allocated for an integer
  • The pointer p points to that memory
  • The value 5 is stored in that memory location.
  • Through it, we can access the stored value.

Dynamic Array Allocation

The new operator can also be used to allocate memory for dynamic arrays. The syntax is slightly different:

data_type* pointer = new data_type[size];

That is, it is basically the same, but we put [] indicating the size of the variable to be allocated. Let’s see it with an example,

int* arr = new int[5]; // Allocates memory for an array of 5 integers

for(int i = 0; i < 5; ++i) {
    arr[i] = i * 2; // Initializes the array with values
}

for(int i = 0; i < 5; ++i) {
    std::cout << arr[i] << " "; // Prints the values of the array
}

std::cout << std::endl;

This example shows how to allocate and use a dynamic array. Here, arr is a pointer to a block of memory that can hold 5 integers.

What is delete

The delete operator is used to free the memory that was dynamically allocated with new.

delete pointer;
  • pointer: This is the pointer that points to the memory that should be freed.

Let’s see it with an example

int* p = new int; // Allocates memory for an integer
*p = 5;           // Stores the value 5 in the allocated memory

delete p;         // Frees the memory
p = nullptr;      // Prevents the pointer from pointing to freed memory

In this example,

  • After using the allocated memory, it is freed with delete
  • nullptr is assigned to the pointer to prevent it from pointing to an address that is no longer valid.

Freeing Dynamic Arrays

When memory is allocated for a dynamic array, it is important to free that memory correctly using the delete[] operator.

delete[] pointer;

For example

int* arr = new int[5]; // Allocates memory for an array of 5 integers

for(int i = 0; i < 5; ++i) {
    arr[i] = i * 2;
}

// Use of the array

delete[] arr; // Frees the memory of the array
arr = nullptr; // Prevents access to freed memory

In this example, the memory allocated for the array is freed using delete[].

It is important to use delete[] instead of delete to avoid undefined behavior (a.k.a something crashing)

Common Errors When Using new and delete

The most common error is forgetting to do a delete when we no longer need a variable, or when we are going to reallocate it.

void memoryLeak() {
    int* p = new int; // Allocates memory for an integer
    // Forgetting to free the memory
    
	p = new int; // Reallocating memory
}

In this case, the pointer p is destroyed when leaving the function, but the allocated memory is not freed, causing a leak.

This is called a memory leak and it is a very common error.


This leads to the program consuming more and more memory and, eventually, crashing 💥 (and it’s also a mess as programmers).

The memory will be freed in any case when the program closes. Don’t think that it’s a permanent issue to the system.

Another common error is accessing memory that has already been freed with delete, which will also cause an error in your program.

int* p = new int(10);
delete p;   // Frees the memory

*p = 5;     // Error: accessing freed memory

This example shows an access to memory after it has been freed, which can cause another crash in your program 💥.

Freeing the same memory more than once is another common error, known as double freeing.

void doubleFree() {
    int* p = new int(10);
    delete p;
    
    delete p; // Error: double freeing
}

In this case, an attempt is made to free the same memory twice, which is a serious error.

Best Practices