The proposal to introduce arrays with the runtime size into the C ++ language (a remote analogue of the VLA in C99) existed at the intermediate stages of the development of the C ++ 11 standard and is easily found in draft versions of the document. However, none of this was included in the final version of the document and the topic of arrays with the runtime size in C ++ was closed.
Nevertheless, many compilers either already had a more or less relevant draft implementation of such functionality, or rushed to implement it even before the release of the final version of C ++ 11. It is these implementations of this functionality that continue to live in some compilers as an extension of the language.
Do not forget that the “example compiled” is in no way a confirmation of the correctness of the code from the point of view of the C ++ language. When using the GCC / Clang compilers, make it a habit to always use the -pedantic-errors parameter to cleanse these implementations from the motley student initiative.
In what cases do you need the new operator
The new operator is primarily needed for unlimited manual control over the lifetime of the objects you manually create. Objects created through new live "forever", i.e. until you destroy them yourself via delete or until your program terminates. Their lifetime is not tied to the boundaries of local blocks.
Also, new needed to select at run-time a specific type of created objects (as in the case of polymorphic classes) and / or their number (in particular, in the case of arrays, this is the size of the array). This can be achieved only by means of dynamic creation of objects.
Much of this can be achieved without new or other variants of dynamic memory allocation, and only competently / cleverly organizing local definitions of objects, but in the general case it will not be possible to overcome the limitations of the lifetime (and there is no point in it).
What is the difference between this array definition and such (besides garbage)
(It's not at all clear what kind of "garbage" you are talking about).
The difference in the first place is that the local array will be automatically destroyed upon completion of the block containing its declaration. And the array created through new[] will not be automatically destroyed at all - it will live until it is destroyed by delete[] .