As I know, an array needs to have a specific size before compiling time in c.
I wonder why this code still works?
int s;
printf("enter the array size: ");
scanf("%d",&s);
int a[s]; // Isn't s value determined at run time?
As I know, an array needs to have a specific size before compiling time in c.
I wonder why this code still works?
int s;
printf("enter the array size: ");
scanf("%d",&s);
int a[s]; // Isn't s value determined at run time?
This code is supported by C99 language specification. This code is also supported by GCC compiler in C89/90 mode as an extension.
So, the answer to your question (why it "works") depends on how you are compiling it. In general case, this will not even compile by a C89/90 compiler.
Its important to understand how memory is allocated to variable by a compiler to give proper answer to your question. There are two modes in which memory is allocated to variable, it can be on a heap or it can be on a stack. Memory on a heap is allocated dynamically. So a variable that is allocated memory on a heap can be given its size during run time.
The arrays in case of C are given memory on a stack. For providing memory on a stack the size of the memory should be known to the compiler during compile time. So that during run time that much memory can be set aside for the variable on the stack. That is the reason you cannot decide the size of the array at run time as far as C language is concerned.
You are confusing two things here.
1) Determining the size of an already allocated array (which your title implies): divide
sizeof()
for the total by the size of one (say, the first) element:2) Dynamically allocating memory as your question asks:
Array sizes need to be known with ANSI 89 C. The 99 version of the spec removed this limitation and allowed for variable sized arrays.
Here is the documentation no the GNU version of this feature
Variable Length Arrays have been part of C language since C99. But they have been made as an feature in C11 - meaning a C11 conforming implementation need not provide it (although, practically all the implementation that support C99 certainly provide VLAs in C11).
You can check if you implementation does not provide VLAs using the macro
__STDC_NO_VLA__
(If it's defined in C99 or C11 mode of compilation, then your implementation doesn't support VLAs).So deciding an array size at runtime is possible in modern C (>= C99) and code like the below is fine:
One obvious drawback of VLAs is that if
s
is quite big and the allocation ofa
coud fail. Worse, there's no way to check if the allocation has failed and you'll run into runtime errors (e.g., segfault). It's essentially undefined behaviour. So you want to avoid VLAs if the array size is too big. Basically, when in doubt, go for dynamic memory allocation (see below).Another issue, much less severe compared to other, with VLAs is that they have automatic storage duration (aka "stack allocated"). So if you want something that lasts for longer duration then the block scope where the VLA is declared, then VLAs are of no help.
In C89, there's no VLA. So using the dynamic memory allocation is the only way. Although, there were some non-standard extensions such as
alloca()
which is similar to VLA and has the same drawbacks as VLAs).If you need to allocate an array with dynamic size, you have to get it from the heap, with malloc().