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 free 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 freed by the programmer during program execution 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 some system input).

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

What is new

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

data_type* pointer = new data_type;
  • data_type: It is the data type for which memory is being allocated.
  • pointer: It 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: It is the pointer that points to the memory that needs to 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 invalid memory address.

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 crashing your program)

Common Mistakes 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, which causes a leak.

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


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 when the program closes. Don’t think of it as a permanent thing to the system.

Another common mistake 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: access to freed memory

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

Freeing the same memory more than once is another common mistake, known as double free.

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

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

Best Practices