When I use a big (> 1MB) automatic-declared array my app crashes. Why?

You've fallen victim to a problem that's rather poorly documented, but there IS a relevant knowledgebase article which I have reproduced in part below (Q97786). The default stack size is 1MB for a Win32 (non-CE) application, and a quick look at the the documentation would lead you believe that it can grow beyond that in units of 1 page, i.e. 4K at a time for x86 machines. But that's not always the case - see the paragraph I've highlighted below.

You can get around this by setting the stack reserve and/or commit values. In Visual C++ 6.0 this is done via Project ~ Settings ~ Link Tab ~ Category: Output. Change the Reserve value to something more appropriate and the problem should go away.


Q97786 

The information in this article applies to:

Microsoft Win32 Application Programming Interface (API), included with:
Microsoft Windows NT, versions 3.1, 3.5, 3.51, 4.0

SUMMARY
By default, space is reserved for applications in the following manner: 

  • 1 megabyte (MB) reserved (total virtual address space for the stack)
  • 1 page committed (total physical memory allocated when stack is created)

Note: The -stack linker option can be used to modify both of these
values. 

The default stack size is taken from the process default reserve stack size. 

The operating system will grow the stack as needed by committing 1 page blocks (4K on an x86 machine) out of the reserved stack memory. Once all of the reserved memory has been committed, Windows NT will attempt to continue to grow the stack into the memory adjacent to the memory reserved for the stack, as shown in the following example on an x86 machine: 

|<--- Total 1 MB for stack --->|<--- Adjacent memory --->|
 --------------------------------------------------------
|    |                         |                         |
| 4K | 1020K ...               | ...                     |
|    |                         |                         |
 -------------------------------------------------------- 

However, once the stack grows to the point that the adjacent area is not free (and this may happen as soon as the reserved 1 MB has been committed), the stack cannot grow any farther. Therefore, it is very risky to rely on this memory being free. Applications should take care to reserve all the memory that will be needed by increasing the amount of memory reserved for the stack.

In other cases, it may be desirable to reduce the amount of memory reserved for the stack. 

The /STACK option in the linker and the STACKSIZE statement in the DEF file can be used to change both the amount of reserved memory and the amount of committed memory. The syntax for each method is shown below: 

/STACK:[reserve][,commit] 

STACKSIZE [reserve][,commit]