3

I was reading a book when I found that array size must be given at time of declaration or allocated from heap using malloc at runtime.I wrote this program in C :

#include<stdio.h>

int main() {
  int n, i;
  scanf("%d", &n);
  int a[n];
  for (i=0; i<n; i++) {
    scanf("%d", &a[i]);
  }
  for (i=0; i<n; i++) {
    printf("%d ", a[i]);
  }
  return 0;
}

This code works fine.

My question is how this code can work correctly.Isn't it the violation of basic concept of C that array size must be declared before runtime or allocate it using malloc() at runtime.I'm not doing any of these two things,then why it it working properly ?

Solution to my question is variable length arrays which are supported in C99 but if I play aroundmy code and put the statement int a[n]; above scanf("%d,&n); then it's stops working Why is it so.if variable length arrays are supported in C ?

dark_shadow
  • 3,503
  • 11
  • 56
  • 81
  • Your book, probably, talked about C89; your compiler uses, probably, C99. They're somewhat different languages (C99 is the evolution of C89; C11 is the evolution of C99). One of the differences is VLA (Variable Length Arrays). – pmg Apr 08 '12 at 12:01
  • How do you know for sure it is really working properly? In cases like these, sometimes it will appear to work for simple cases but go screwy on expansion. It's highly likely the internal memory is corrupted even in the "successful" execution- you're just getting lucky that it doesn't wreck the program. Or as others point out, you may be using C99. – Platinum Azure Apr 08 '12 at 12:02
  • VLAs are a PITA (especially if large). If you can avoid them, do so :) – pmg Apr 08 '12 at 12:08

4 Answers4

4

The C99 standard supports variable length arrays. The length of these arrays is determined at runtime.

Charles Salvia
  • 52,325
  • 13
  • 128
  • 140
  • 1
    If the length of these arrays is determined at runtime then how the memory allocation for these arrays take place ? Are they allocated storage on heap just as we do in normal runtime arrays using malloc() or on stack ? – dark_shadow Apr 08 '12 at 12:10
  • @dark_shadow, that depends on the implementation. A heap allocation can be avoided by simply moving up the stack pointer at runtime, which is what the `alloca` function (an extension provided by some platforms, such as Microsoft and GNU) does. – Charles Salvia Apr 08 '12 at 12:59
3

Since C99 you can declare variable length arrays at block scope.

Example:

void foo(int n)
{
    int array[n];

    // Initialize the array
    for (int i = 0; i < n; i++) {
        array[i] = 42;
    }
}
ouah
  • 142,963
  • 15
  • 272
  • 331
  • Can you please explain the meaning of block scope ? – dark_shadow Apr 08 '12 at 12:24
  • 1
    @dark_shadow you can only declare variable length array in the body of a function. – ouah Apr 08 '12 at 12:35
  • Thanks ouah for the help.Please take a look at my modified question.I have added a part in it.Can you please tell me the reason for that ? Thanks. – dark_shadow Apr 08 '12 at 12:46
  • If you put the declaration of `int a[n]` above the `scanf`, then `n` will not be initialized when declaring `a` array. So you can end up with any `n` value. – ouah Apr 08 '12 at 12:52
  • Thanks got the point.I have one more question.Are these variable length arrays are declared memory on stack or on heap ? I think it should be allocated on stack as they are bound to block scope and since everything in a block scope comes on stack I assume this should go with the rules.Am I right ? – dark_shadow Apr 08 '12 at 12:53
0

C will be happy as long as you've declared the array and allocated memory for it before you use it. One of the "features" of C is that it doesn't validate array indices, so it's the responsibility of the programmer to ensure that all memory accesses are valid.

Adam Liss
  • 47,594
  • 12
  • 108
  • 150
0

Variable length arrays are a new feature added to C in C99.

"variable length" here means that the size of the array is decided at run-time, not compile time. It does not mean that the size of the array can change after it is created. The array is logically created where it is declared. So your code looks like.

int n, i;

Create two variables n and i. Initially these variables are uninitialised.

scanf("%d", &n);

Read a value into n.

int a[n];

Create an array "a" whose size is the current value of n.

If you swap the second and third steps you try to create an array whose size is determined by an uninitalised value. This is not likely to end well.

The C standard does not specify exactly how the array is stored but in practice most compilers (I belive there are some exceptions) will allocate it on the stack. The normal way to do this is to copy the stack pointer into a "frame pointer" as part of the function preamble. This then allows the function to dynamically modify the stack pointer while keeping track of it's own stack frame.

Variable length arrays are a feature that should be used with caution. Compilers typically do not insert any form of overflow checking on stack allocations. Operating systems typically insert a "gaurd page" after the stack to detect stack overflows and either raise an error or grow the stack, but a sufficiently large array can easilly skip over the guard page.

plugwash
  • 9,724
  • 2
  • 38
  • 51