1

So you can use the "new" operator to allocate memory dynamically at run-time. But what about the following case:

#include <iostream>

using namespace std;

int main ()
{
    int size;

    cin >> size;

    int a[size];
}

Here the size of the array cannot possibly be known at compile time, and it is determined at run-time. How is this different than dynamically allocated memory?

This question is partly motivated by the statement on this page:

There is a substantial difference between declaring a normal array and allocating dynamic memory for a block of memory using new. The most important difference is that the size of a regular array needs to be a constant expression, and thus its size has to be determined at the moment of designing the program, before it is run, whereas the dynamic memory allocation performed by new allows to assign memory during runtime using any variable value as size.

murray
  • 113
  • 5
  • "dynamic allocation" is a general computer science term and people use it without precise meaning. In the C++ Standard, "dynamic allocation" refers only to memory allocated by `new` or `operator new`. In the C Standard the term is not used at all. – M.M Nov 02 '15 at 04:09

2 Answers2

2

This is legal in C, but not C++. However, some C++ compilers allow it as an extension. This question covers that part in more detail.

It's different than typical dynamic memory allocation in the sense that the memory is allocated on the stack (rather than the heap) and with automatic storage duration (meaning it gets freed automatically at the end of the scope). When execution exits the scope that contains a, it will automatically be freed. This is not the case with memory allocated via new/malloc.

It's still a form of dynamic memory allocation (obviously, since the memory has to be allocated on the stack dynamically), but it's not the type of dynamic memory allocation people usually mean when using that term.

Community
  • 1
  • 1
Cornstalks
  • 37,137
  • 18
  • 79
  • 144
1

Variable-length automatic arrays are allowed in ISO C99, and as an extension GCC accepts them in C90 mode and in C++. These arrays are declared like any other automatic arrays, but with a length that is not a constant expression. The storage is allocated at the point of declaration and deallocated when the block scope containing the declaration exits. For example:

 FILE *
 concat_fopen (char *s1, char *s2, char *mode)
 {
   char str[strlen (s1) + strlen (s2) + 1];
   strcpy (str, s1);
   strcat (str, s2);
   return fopen (str, mode);
 }

Jumping or breaking out of the scope of the array name deallocates the storage. Jumping into the scope is not allowed; you get an error message for it.

As an extension, GCC accepts variable-length arrays as a member of a structure or a union. For example:

 void
 foo (int n)
 {
   struct S { int x[n]; };
 }

You can use the function alloca to get an effect much like variable-length arrays. The function alloca is available in many other C implementations (but not in all). On the other hand, variable-length arrays are more elegant.

There are other differences between these two methods. Space allocated with alloca exists until the containing function returns. The space for a variable-length array is deallocated as soon as the array name's scope ends. (If you use both variable-length arrays and alloca in the same function, deallocation of a variable-length array also deallocates anything more recently allocated with alloca.)

You can also use variable-length arrays as arguments to functions:

 struct entry
 tester (int len, char data[len][len])
 {
   /* ... */
 }

The length of an array is computed once when the storage is allocated and is remembered for the scope of the array in case you access it with sizeof.

If you want to pass the array first and the length afterward, you can use a forward declaration in the parameter list—another GNU extension.

 struct entry
 tester (int len; char data[len][len], int len)
 {
   /* ... */
 }

The ‘int len’ before the semicolon is a parameter forward declaration, and it serves the purpose of making the name len known when the declaration of data is parsed.

You can write any number of such parameter forward declarations in the parameter list. They can be separated by commas or semicolons, but the last one must end with a semicolon, which is followed by the “real” parameter declarations. Each forward declaration must match a “real” declaration in parameter name and data type. ISO C99 does not support parameter forward declarations.

Vedanshu
  • 2,230
  • 23
  • 33