Are 'new' and 'delete' getting deprecated in C++?

C++ArraysDynamic Memory-AllocationStatic Memory-Allocation

C++ Problem Overview


I stumbled upon a quiz that involved array declaration with different sizes. The first thing that came to my mind is that I would need to use dynamic allocation with the new command, like this:

while(T--) {
   int N;
   cin >> N;
   int *array = new int[N];
   // Do something with 'array'
   delete[] array;
}

However, I saw that one of the solutions allowed the following case:

while(T--) {
    int N;
    cin >> N;
    int array[N];
    // Do something with 'array'
}

After a bit of research I read that g++ allows this, but it kept me thinking, in which cases is it then necessary to use dynamic allocation? Or is it that the compiler translates this as dynamic allocation?

The delete function is included. Note, however, that the question in here is not about memory leaks.

C++ Solutions


Solution 1 - C++

Neither snippet you show is idiomatic, modern C++ code.

new and delete (and new[] and delete[]) are not deprecated in C++ and never will be. They are still the way to instantiate dynamically allocated objects. However, as you have to always match a new with a delete (and a new[] with a delete[]), they are best kept within (library) classes that ensure this for you. See https://stackoverflow.com/questions/6500313/why-should-c-programmers-minimize-use-of-new.

Your first snippet uses a "naked" new[] and then never delete[]s the created array. That's a problem. std::vector does everything you need here just fine. It will use some form of new behind the scenes (I won't dive into implementation details), but for all you have to care, it's a dynamic array but better and safer.

Your second snippet uses "variable length arrays" (VLAs), a C feature that some compilers also allow in C++ as an extension. Unlike new, VLAs are essentially allocated on the stack (a very limited resource). But more importantly, they are not a standard C++ feature and should be avoided because they are not portable. They certainly do not replace dynamic (i.e. heap) allocation.

Solution 2 - C++

Well, for starters, new/delete are not getting deprecated.

In your specific case, they're not the only solution, though. What you pick depends on what got hidden under your "do something with array" comment.

Your 2nd example uses a non-standard VLA extension which tries to fit the array on the stack. This has certain limitations - namely limited size and the inability to use this memory after the array goes out of scope. You can't move it out, it will "disappear" after the stack unwinds.

So if your only goal is to do a local computation and then throw the data away, it might actually work fine. However, a more robust approach would be to allocate the memory dynamically, preferrably with std::vector. That way you get the ability to create space for exactly as many elements as you need basing on a runtime value (which is what we're going for all along), but it will also clean itself up nicely, and you can move it out of this scope if you want to keep the memory in use for later.

Circling back to the beginning, vector will probably use new a few layers deeper, but you shouldn't be concerned with that, as the interface it presents is much superior. In that sense, using new and delete can be considered discouraged.

Solution 3 - C++

Your second examples uses variable length arrays (VLAs), which are actually a C99 (not C++!) feature, but nonetheless supported by g++.

See also this answer.

Note that variable length arrays are different from new/delete and do not "deprecate" them in any way.

Be also aware that VLAs are not ISO C++.

Solution 4 - C++

Modern C++ provides easier ways to work with dynamic allocations. Smart pointers can take care about the cleanup after exceptions (that may happen anywhere if allowed) and early returns, as soon as the referenced data structures go out of scope, so may make sense to use these instead:

  int size=100;

  // This construct requires the matching delete statement.
  auto buffer_old = new int[size];

  // These versions do not require `delete`:
  std::unique_ptr<int[]> buffer_new (new int[size]);
  std::shared_ptr<int[]> buffer_new (new int[size]); 
  std::vector<int> buffer_new (size);  int* raw_access = buffer_new.data();

From C++ 14 you can also write

auto buffer_new = std::make_unique<int[]>(size);

this looks even nicer and would prevent memory leak if the allocation fails. From C++ 20 you should be able to do as much as

auto a = std::make_shared<int[]>(size);

this for me still does not compile at the time of writing with gcc 7.4.0. In these two examples we also use auto instead of type declaration on the left. In all cases, use array as usual:

buffer_old[0] = buffer_new[0] = 17;

Memory leaks from new and crashes from doubled delete is something C++ has been bashed for many years, being the "central point" of argumentation for switching into other languages. Maybe better to avoid.

Solution 5 - C++

new and delete are not getting deprecated.

The objects created by new operator can be passed by reference. The objects can be deleted using delete.

new and delete are the foundational aspects of the language. Persistence of an object can be managed using new and delete. These are definitely not going to be deprecated.

The statement - int array[N] is a way of defining an array. The array can be used within the scope of the enclosing code block. It cannot be passed like how an object is passed to another function.

Solution 6 - C++

The first example needs a delete[] at the end, or you will have a memory leak.

The second example use variable array length that is not supported by C++; it only allows constant-expression for array length.

In this case it is useful to use std::vector<> as solution; that wraps all the actions you can perform on an array into a template class.

Solution 7 - C++

The syntax looks like C++, but the idiom is similar to plain old Algol60. It was common to have code blocks like this:

read n;
begin
    integer array x[1:n];
    ... 
end;

The example could be written as:

while(T--) {
    int N;
    cin >> N;
    {
        int array[N];
        // Do something with 'array'
    }
}

I sometimes miss this in the current languages ;)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionlearning_dudeView Question on Stackoverflow
Solution 1 - C++Max LanghofView Answer on Stackoverflow
Solution 2 - C++Bartek BanachewiczView Answer on Stackoverflow
Solution 3 - C++andreeeView Answer on Stackoverflow
Solution 4 - C++Audrius MeškauskasView Answer on Stackoverflow
Solution 5 - C++GopinathView Answer on Stackoverflow
Solution 6 - C++Zig RazorView Answer on Stackoverflow
Solution 7 - C++kdoView Answer on Stackoverflow