Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ array sizes without constant expressions

Tags:

I'm reading Stroustrup's A Tour of C++. On page 9, he states:

"The size of an array must be a constant expression."

Yet later, on pg. 16, he uses the following code sample:

void vector vector_init(Vector& v, int s) {   v.elem = new double[s]; // Allocate an array of s doubles   v.sz = s; } 

Here s is not a constant expression, so how is initializing v.elem to new double[s] legal?

like image 907
George Avatar asked Mar 23 '16 12:03

George


People also ask

Can array size be an expression in C?

It is true, in C++. What you are using is a non-standard extension provided by GCC specifically, called Variable Length Arrays.

Can we declare array without size in C?

You can declare an array without a size specifier for the leftmost dimension in multiples cases: as a global variable with extern class storage (the array is defined elsewhere), as a function parameter: int main(int argc, char *argv[]) . In this case the size specified for the leftmost dimension is ignored anyway.

Can you declare an array without assigning the size of an array?

Answer: No. It is not possible to declare an array without specifying the size. If at all you want to do that, then you can use ArrayList which is dynamic in nature.

Do array size can be of variable expression?

Variable length arrays are also known as runtime sized or variable sized arrays. The size of such arrays is defined at run-time. Variably modified types include variable length arrays and pointers to variable length arrays. Variably changed types must be declared at either block scope or function prototype scope.


2 Answers

There is a differentiation between allocated arrays (i.e. those created with a new[] expression, like new double[s]), whose lifetimes must be managed by the code (via delete[]) and declared arrays, whose lifetimes are managed by their scope alone:

int* p = new int[s];  // allocated array, p has type int* int q[10];            // declared array, q has type int[10] std::vector<int> u;   // has member allocated array std::array<int, 5> v; // has member declared array 

The differentiation is not based on stack/heap. A declared array can be heap allocated (e.g. new array<int,5>) or not on the stack (e.g. static double x[100];)

With an allocated array, the size does not have to be a constant expression. The size will simply be encoded into the block of memory yielded by the allocator somehow (for instance the four leading bytes before the actual data starts) so that the corresponding delete[] knows how many elements to delete.

With a declared array (or non-allocated array, no new/malloc/etc.), the size must be coded into the type, so that the destructor knows what to do. The only allowed, standard array declaration is:

T D[constant-expression_opt]; 

(where D is a declarator that could be a name or another array declaration, etc.) Declared arrays are not limited to the stack. Note that, for added confusion, the constant-expression is optional.

Arrays offer many sources of confusion in C++. Allocated and declared arrays have different size rules, different management practices, but you can assign a T* to either and they're equivalently indexed. An allocated array is a pointer (that's all you get), but a declared array decays to a pointer (but is an array!).


Note that there is a concept of a Variable Length Array (VLA). gcc, for instance, supports them as an extension, but they are non-standard C++. It gets periodically proposed though, and you can see this question for more information about them.

like image 51
Barry Avatar answered Oct 01 '22 13:10

Barry


When creating an array whose memory is managed by compiler, its size must be (compile time) constant. For ex:

int a[5]; const int sz = 7; int b[sz] = {0}; 

(Some languages for ex: C (C99 onwards) support dynamic array size)

If you want a dynamically sized array (Example snippet given by you), you need to allocate memory for it by yourself you'll also need to free it with delete when you're done. Size of such arrays can be non-const also. Moreover you need to manage the memory by yourself, allocation may fail and operators (for example sizeof) would operate on the pointer rather than array.

In modern C++ (C++11 onwards), even stl container std::array must have a constant size.

like image 30
Mohit Jain Avatar answered Oct 01 '22 13:10

Mohit Jain