C and large arrays
This is an old page from the time when we used Sun-computers. The information is still valid though.
Some of the assignments require that you use large arrays. This may be a problem in C on a Sun-computer (and perhaps on other systems as well). Consider the following program:
#include <stdio.h> #define _N 2000000 main() { int k; double large_array[_N]; for(k = 0; k < _N; k++) large_array[k] = 1; printf("Last %f\n", large_array[_N - 1]); return 0; }
When we try to run it we get:
% cc stack_problems_1.c
% a.out
Segmentation fault
The reason is that large_array
is allocated on the stack, which
has a limited size. We can find out the size by using the command
limit
. Thus:
% limit (works provided you use tcsh)
cputime unlimited
filesize unlimited
datasize 2097148 kbytes
stacksize 8192 kbytes
coredumpsize 0 kbytes
vmemoryuse unlimited
descriptors 1024
So, the stack is limited to 8192 kbyte (8 Mbyte), but we need 2000000 * 8 / 1024 kbyte, i.e. 15625 kbyte (the stack is used for some other purposes as well so it must be a bit larger). So, let us increase the stack size and try again:
% limit stacksize 15700 kbytes
% a.out
Last 1.000000
Another way is to store the array in a segment in a.out
. If
we make large_array
static, i.e. we have the type declaration:
static double large_array[_N];
our program will work with the default stack size. The array is now stored in the bss-segment.
% cc stack_problems_2.c
% limit stacksize
stacksize 8192 kbytes
% a.out
Last 1.000000
% size a.out
text data bss dec
hex filename
2589 252 16000000 16002841 f42f19
a.out
One drawback with static variables is that they exist for the lifetime of
the program (even if we do not use the array). So, yet another way (common)
is the use dynamic memory allocation (i.e. we use malloc
/
free
) placing the array on the heap:
#include <stdio.h> #include <stdlib.h> #define _N 2000000 int main() { int k; double *large_array; if ( (large_array = malloc(_N * sizeof(double))) == NULL) { printf("Could not malloc large_array.\n"); exit(1); } for(k = 0; k < _N; k++) large_array[k] = 1; printf("Last %f\n", large_array[_N - 1]); free(large_array); return 0; }