Home > Net >  Undefined behaviour of delete operator
Undefined behaviour of delete operator

Time:05-03

I am relatively new to C and I'm learning about pointers. I was trying to dynamically allocate some memory for an array and found this issue.

Here is my code,

#include <iostream>

int main(){
    int n = 5;
    int *arr = new int(n*(sizeof(int)));

    for(int i=0; i<n; i  )
        *(arr i) = i 1;

    delete[] arr;

    for(int i=0; i<n; i  )
        std::cout << *(arr i) << " ";
}

and the expected output is some garbage value since I'm freeing the memory with delete operator, however, this is my output instead:

First run: 755597344 47626 2043 4 5

Second run: -1437908960 62859 2043 4 5

Third run: -902037472 965 2043 4 5

I've tried several runs, but only first 3 values change, and the others seem as the array was still there, what could be the explanation for this?

CodePudding user response:

In the small piece of code there are multiple errors and problems:

  • The expression new int(n*(sizeof(int))) allocates a single int value and initializes it to the value n*(sizeof(int)).

    If you want to allocate space for an array of int values you need to use new[], as in new int[n]

  • Because of the above problem, you will go out of bounds of the allocated memory, leading to undefined behavior.

  • Once you fix issue number 1, you need to pair new[] with the delete[] operator. Mismatching operators also leads to undefined behavior.

  • And lastly, once you have deleted memory you can no longer access it, and any attempt of dereferencing the pointer will again lead to undefined behavior.

All in all the program should look something like this:

#include <iostream>
#include <cstdlib>

int main()
{
    constexpr std::size_t n = 5;

    // Allocate memory
    int* arr = new[n];

    // Initialize the memory
    for (std::size_t i = 0; i < n;   i)
    {
        arr[i] = i   1;
    }

    // Display the memory
    for (std::size_t i = 0; i < n;   i)
    {
        std::cout << "arr[" << i << "] = " << arr[i] << '\n';
    }

    // Free the memory
    delete[] arr;
}

With all of the above said and done, there are better ways to create arrays of either fixed or dynamic size.

If you have a fixed-size array, whose size is known at compile-time and whose size will never change during run-time, use std::array instead:

// Create and initialize array
std::array<int, 5> arr = {{ 1, 2, 3, 4, 5 }};

// Display array
for (int value : arr)
{
    std::cout << value << '\n';
}

If the size is not known at compile-time, or the size will need to change during run-time, use std::vector instead:

// Create a vector with five "zero-initialized" elements
std::vector<int> arr(5);

CodePudding user response:

new int(n*(sizeof(int)));

This allocates only single int and set value as n*(sizeof(int)).

If you want array of int, you have to do like below.

   int *arr = new int[n];
  • Related