The total size of a stack allocated array is limited by the maximum size of the stack.
Right. Typically, there is *no* warning given if you exceed this size.
Not at compile time, but, depending on the C implementation, you may receive a runtime error when you allocate or initialize the array (remember that you must initialize all stack variables). On a Unix-like system that provides unmapped address space (guard pages) between stack segments, such as Mac OS X, you will typically receive a Segmentation Fault. In an embedded system that does not provide memory protection, you may receive no error at all.
Consider vla.c: #include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[]) {
if (argc < 2) {
fprintf(stderr, "usage: %s byte-count\n", argv[0]);
return EXIT_FAILURE;
}
unsigned long sz = strtoul(argv[1], NULL, 0);
char vla[sz];
printf("Array size: %#lx\n", sizeof vla);
memset(vla, 0, sizeof vla);
return EXIT_SUCCESS;
}
Here is the execution log on a G5 Quad running Mac OS X 10.4.8. Note that in some cases you receive the Segmentation Fault upon allocation (before the printf() call) and in some cases you receive the fault during initialization (after the printf() call). This behavior may vary on an Intel system. % gcc -std=c99 -Wall -Wextra -pedantic -o vla vla.c
% ./vla 0
Array size: 0
% ./vla 1
Array size: 0x10000
% ./vla 0x100000
Array size: 0x100000
% ./vla 0x1000000
Segmentation fault
% ./vla 0x10000000
Array size: 0x10000000
Segmentation fault
% ./vla 0x100000000
Array size: 0xffffffff
Segmentation fault
if you call foo with (say) 1200000, then, at least under gcc, the array will be silently given a garbage value and you use it at your own (and your customer's) risk. It is not clear what the maximum safe size of a dynamically sized array is, but gcc seems to limit it to 64K bytes.
Not sure what is meant by "silently given a garbage value." All stack variables have garbage values until you initialize them. The value 1200000 works fine with the vla.c given above, but this is system and program dependent.
% ./vla 1200000
Array size: 0x124f80
The maximum safe size of a dynamically sized array is at least as large as the maximum safe size of an equivalent statically sized array, and possibly larger. It is both system and program dependent: it depends on the system's maximum stack size (for Unix see getrlimit(2)) and your thread's worst-case stack usage (which is typically not easily determined, and is further complicated by dynamic allocation of stack space).
I have seen no 64K limitation with GCC. The default stack limit on my system is 8MB. As expected, vla.c fails with arrays that are close to 8MB in size (there is some initial stack usage, between 4K and 32K). Increasing the stack limit to 64MB works as expected. [/p] % ./vla 0x700000
Array size: 0x700000
% ./vla 0x800000
Segmentation fault
% ./vla 0x7ff000
Segmentation fault
% ./vla 0x7f8000
Array size: 0x7f8000
% limit stacksize
stacksize 8192 kbytes
% ./vla 0x800000
Segmentation fault
% limit stacksize unlimited
% limit stacksize
stacksize 65536 kbytes
% ./vla 0x800000
Array size: 0x800000
% ./vla 0x3f00000
Array size: 0x3f00000
% ./vla 0x4000000
Segmentation fault
%
by Tim — Oct 21
Right.
Typically, there is *no* warning given if you exceed this size.
Not at compile time, but, depending on the C implementation, you may receive a runtime error when you allocate or initialize the array (remember that you must initialize all stack variables). On a Unix-like system that provides unmapped address space (guard pages) between stack segments, such as Mac OS X, you will typically receive a Segmentation Fault. In an embedded system that does not provide memory protection, you may receive no error at all.
Consider vla.c:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char* argv[]) { if (argc < 2) { fprintf(stderr, "usage: %s byte-count\n", argv[0]); return EXIT_FAILURE; } unsigned long sz = strtoul(argv[1], NULL, 0); char vla[sz]; printf("Array size: %#lx\n", sizeof vla); memset(vla, 0, sizeof vla); return EXIT_SUCCESS; }
Here is the execution log on a G5 Quad running Mac OS X 10.4.8. Note that in some cases you receive the Segmentation Fault upon allocation (before the printf() call) and in some cases you receive the fault during initialization (after the printf() call). This behavior may vary on an Intel system.
% gcc -std=c99 -Wall -Wextra -pedantic -o vla vla.c % ./vla 0 Array size: 0 % ./vla 1 Array size: 0x10000 % ./vla 0x100000 Array size: 0x100000 % ./vla 0x1000000 Segmentation fault % ./vla 0x10000000 Array size: 0x10000000 Segmentation fault % ./vla 0x100000000 Array size: 0xffffffff Segmentation fault
if you call foo with (say) 1200000, then, at least under gcc, the array will be silently given a garbage value and you use it at your own (and your customer's) risk. It is not clear what the maximum safe size of a dynamically sized array is, but gcc seems to limit it to 64K bytes.
Not sure what is meant by "silently given a garbage value." All stack variables have garbage values until you initialize them. The value 1200000 works fine with the vla.c given above, but this is system and program dependent.
% ./vla 1200000 Array size: 0x124f80
The maximum safe size of a dynamically sized array is at least as large as the maximum safe size of an equivalent statically sized array, and possibly larger. It is both system and program dependent: it depends on the system's maximum stack size (for Unix see getrlimit(2)) and your thread's worst-case stack usage (which is typically not easily determined, and is further complicated by dynamic allocation of stack space).
I have seen no 64K limitation with GCC. The default stack limit on my system is 8MB. As expected, vla.c fails with arrays that are close to 8MB in size (there is some initial stack usage, between 4K and 32K). Increasing the stack limit to 64MB works as expected. [/p]
% ./vla 0x700000 Array size: 0x700000 % ./vla 0x800000 Segmentation fault % ./vla 0x7ff000 Segmentation fault % ./vla 0x7f8000 Array size: 0x7f8000 % limit stacksize stacksize 8192 kbytes % ./vla 0x800000 Segmentation fault % limit stacksize unlimited % limit stacksize stacksize 65536 kbytes % ./vla 0x800000 Array size: 0x800000 % ./vla 0x3f00000 Array size: 0x3f00000 % ./vla 0x4000000 Segmentation fault %