10

As local variables are also called automatic variables, and are supposed to be allocated memory at run time, when function is accessed.

int main(){
    int a; // declaration 
    return 0;
}

int main(){
    int a[]; // compilation error, array_size missing
    return 0;
}

int main(){
    int a[2]; // declaration, but can't work without array_size, 
              // so at compile time it is checked!
    return 0;
}

My question is whether it's just a rule to give array_size in declaration in C, or memory is allocated at compile time for array (still local variable)

How does it work?

An array is a variable as per C programming by K&R. pg no 161.

joce
  • 9,624
  • 19
  • 56
  • 74
linuxD
  • 229
  • 1
  • 3
  • 10
  • Static arrays' size is determined at compile time. But they are allocated when the function is called. – sgarizvi Mar 13 '13 at 12:32
  • 5
    How possibly could be a variable allocated at compile time? –  Mar 13 '13 at 12:35
  • 1
    @sgar91: There aren't any static arrays in that code. – netcoder Mar 13 '13 at 12:36
  • @netcoder Then what is `int a[2];` called? – sgarizvi Mar 13 '13 at 12:38
  • 1
    @H2CO3 By the compiler, of course. I'm sure it allocates *plenty* of them. Oh.. you meant in the program *being compiled*.. nm. =P – WhozCraig Mar 13 '13 at 12:38
  • so is it array_size is just syntax check at compile time, not related to allocation? – linuxD Mar 13 '13 at 12:38
  • 1
    @sgar91 that would be a local fixed-length array variable. – WhozCraig Mar 13 '13 at 12:39
  • 1
    @linuxDeveloper Nah. The compiler emits instructions **at compile time** that make the program allocate memory **at runtime.** –  Mar 13 '13 at 12:41
  • @H2CO3 ok, for instruction generation its need array_size, but the real allocation happens at runtime. But if I try to declare a[999999999], compiler error, too large!. And we can not say its out of integer range. a is still int array and can hold only int type variables. At compile time it checks is this memory available.Or I am missing somewhere. – linuxD Mar 13 '13 at 12:46
  • @linuxDeveloper: declaring a[999999999] is absolutely fine in C, but is fairly likely to cause a stack overflow. Your compiler is probably telling you this. – teppic Mar 13 '13 at 12:51
  • @teppic but its telling me at compile time only, so its checking for available memory or what is it? – linuxD Mar 13 '13 at 12:54
  • 1
    @linuxDeveloper: your compiler knows how large the stack is (the space available for automatic variables), so knows the array is too large at compile time. If it's just a warning, it'll compile anyway, but if you use the array, you will probably get a crash. – teppic Mar 13 '13 at 12:57
  • @H2CO3 I am just confused by this Wikipedia article http://en.wikipedia.org/wiki/Static_memory_allocation and what you said. A program is allocated memory by OS only when it is executing, then how could possibly static or global variables be allocated during compile time as also stated in the answer below? – ajay Feb 01 '14 at 13:39
  • 1
    @ajay the Wikipedia article is at best misleading. Think about it. Again, the compiler emits code at compile time that allocates memory at runtime. –  Feb 01 '14 at 13:43
  • @H2CO3 Yes and it doesn't even make sense that memory is allocated before the program is executed. That way, I'd keep eating up ram as I compile more programs. Sounds ludicrous! So the compiler emits code to store static/global variables in the data segment or the bss segment of the address space allocated to the executing program? – ajay Feb 01 '14 at 13:55
  • 1
    @ajay Of course. What else could it possibly do? –  Feb 01 '14 at 13:56
  • @H2CO3 I was misled by the Wikipedia article and didn't think much about it! Thanks for clearing things up :) Also, I should be wary of Wiki articles and should consult textbooks. – ajay Feb 01 '14 at 14:00

7 Answers7

11

When you declare local variable, the size of it is known at a compile time, but memory allocation occurs during execution time.

So in your examples, array without a size is clearly a problem to compiler, as it doesn't know what is the size to include into assembler code.

If you don't know the size of an array, you can always use pointer types and malloc/free or even alloca. The first two operate on heap, and alloca actually uses stack.

The notable exception is static variables. The storage for them is allocated at a compile/link time already and can't be changed at runtime.

Examples:

int main(int argc, const char *argv[])
{
    int a; // a is a sizeof(int) allocated on stack
}

int main(int argc, const char *argv[])
{
    int a[2]; // a is a sizeof(int)*2 allocated on stack
}

int main(int argc, const char *argv[])
{
    int *a; // a is a sizeof(int*) allocated on stack (pointer)
    a = alloca(sizeof(int)*4); // a points to an area with size of 4 integers
                               // data is allocated on stack
}

int main(int argc, const char *argv[])
{
    static int a; // a is allocated in data segment, keeps the value
}
Valeri Atamaniouk
  • 5,125
  • 2
  • 16
  • 18
2
int main(){
    int a[2];
    return 0;
}

Here, int a[2]; is a definition of a variable named a. a is an array of two int.

What happens in practice is that the compiler emits code to use space on the stack for 2 adjacent int objects (probably 8 bytes, but the size of int is up to the implementation). That's assuming of course that the object isn't removed by the optimizer because you never use it.

The compiler error you got for int a[999999999]; is due to some hard limit enforced by the compiler, because it knows (or anyway assumes) there will never be enough stack for that.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
  • Thanks for your help. What we call to int a[2]={9,8,4}; a declaration or definition. – linuxD Mar 13 '13 at 12:53
  • @linuxDeveloper: that's an invalid attempt at a definition (too many items in the {} list). Be aware that definitions *are* declarations, but they're specific kinds of declarations that create the objects they declare. – Steve Jessop Mar 13 '13 at 12:53
  • thanks again. May I get some details about this definitions are declarations, any link please, because its a frequently asked question. – linuxD Mar 13 '13 at 12:58
1

There's a difference between local and automatic variables in C. A local variable may be automatic or static, which determines whether the memory for it is allocated on the stack, or permanently, when the program is first executed.

With this code:

int main(){
  int a[];    //compilation error, array_size missing
  return 0;
}

This is an incomplete array. The error is because the compiler doesn't know how many ints the program will need to allocate.

teppic
  • 8,039
  • 2
  • 24
  • 37
0

As sgar91 stated in the comments, an array such as in your example is allocated when a function is called and must be determinate in size. If you need dynamic arrays, you must allocate the memory on the heap.

int *values = malloc(sizeof(int) * array_count);
Inisheer
  • 20,376
  • 9
  • 50
  • 82
0

Automatic allocation happens when you declare an automatic variable, such as a function argument or a local variable. The space for an automatic variable is allocated when the compound statement containing the declaration is entered, and is freed when that compound statement is exited.

Rajeshirke
  • 21
  • 1
  • 3
0

Thats the point in C, where arrays and pointers aren't the same.

Take this example:

int main(){
   int a[5];
   int * b = malloc(sizeof(int) * 5);

  printf("sizeof a = %d\n",sizeof a);
  printf("sizeof int[5] = %d\n",sizeof(int[5]));
  printf("sizeof b = %d\n",sizeof b);

  free(b);
  return 0;
}

This will return:

sizeof a = 20
sizeof int[5] = 20
sizeof b = 4

The variable a is internal declared as int[5], an integer pointer pointing to a memory block with space for 5 integers.

flyingOwl
  • 244
  • 1
  • 5
-1

For local variables, the memory they consume is on the stack. This means that they must have a fixed size known at compile time, so that when the function is called, the exact amount of memory needed is added to the stack by changing the value of the stack pointer. This is why the array must have a size: the number of bytes on the stack must change by a fixed amount when the function is called.

Calls to malloc() and similar allocate memory from the heap; memory allocated in this way at runtime can be of variable size.