Programmers tend to approach every problem by first writing more code. Which then has to be maintained. Every problem is not a nail...
More code is not the simplest, most effective solution here. More code is also likely to produce an executable that's slower.
Stack memory is just memory - it's no different from heap memory. It's just managed by the process differently, and is subject to different resource limits. There's no real difference to the OS whether a process uses 1 GB of memory on its stack, or 1 GB from its heap.
In this case, the stack size limit is likely an artificial configuration setting. On a Linux system, the stack size limit can be reset for a shell and its child processes:
bash-4.1$ ulimit -s unlimited
bash-4.1$ ulimit -s
unlimited
bash-4.1$
See this question and its answers for more details.
All POSIX-compliant systems should have similar features, as the stack-size limit is a POSIX-standard resource limit.
Also, you can run a thread with an arbitrarily large stack quite easily:
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <stdio.h>
void *threadFunc( void *arg )
{
double array[1024][1024][64];
memset( array, 0, sizeof( array ) );
return( NULL );
}
int main( int argc, char **argv )
{
// create and memset the stack lest the child thread start thrashing
// the machine with "try to run/page fault/map page" cycles
// the memset will create the physical page mappings
size_t stackSize = strtoul( argv[ 1 ] ? argv[ 1 ] : "1073741824",
NULL, 0 );
void *stack = mmap( 0, stackSize, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, -1, 0 );
memset( stack, 0, stackSize );
// create a large stack for the child thread
pthread_attr_t attr;
pthread_attr_init( &attr );
pthread_attr_setstacksize( &attr, stackSize );
pthread_attr_setstackaddr( &attr, stack );
pthread_t tid;
pthread_create( &tid, &attr, threadFunc, NULL );
void *result;
pthread_join( tid, &result );
return( 0 );
}
Error checking has been omitted.
This also works if you run ulimit -s unlimited
before running the compiled program (and of course if the machine has enough virtual memory...):
#include <string.h>
int main( int argc, char **argv )
{
double array[1024][1024][64];
memset( array, 0, sizeof( array ) );
return( 0 );
}