Each application has one data segment called the automatic data segment, which may contain up to 64K. The automatic data segment contains the following kinds of data:
Type | Description |
Task header | Contains 16 bytes of information that Windows maintains for each application. The task header is always located in the first 16 bytes of the automatic data segment. |
Static data | Includes all C-language variables that are declared as static or extern, either explicitly or by default. |
Stack | Stores automatic data. The stack has a fixed size, but the active area within the stack grows and contracts as functions execute and return. Each time a function is called, the return address is pushed onto the active portion of the stack, along with the parameter values passed to the function. |
Local heap | Contains all local dynamic data. |
The following figure shows the layout of the application's automatic data segment:
The size of the stack is always fixed for a given application. You specify the size, in bytes, of the stack by using the STACKSIZE statement in your application's module-definition (.DEF) file. Windows enforces a minimum stack size of 5K. You should experiment with your application to determine an optimum stack size, although keep in mind that the results of a stack overflow are unpredictable.
The size of the local heap is set to an initial value for the application according to the HEAPSIZE statement in your application's .DEF file. The local heap will grow as needed when you call the LocalAlloc function. For applications, the initial size of the local heap must be at least large enough to hold the current environment variables; a minimum heap size of 1K is recommended. If your application does not require access to environment information, you can link your application to an object file that will prevent this initialization information from being placed in the heap. For more information, see Chapter 14, “C and Assembly Language.”
If your application requests memory from the local heap beyond what is available, the heap can grow until the total data segment reaches 64K. If some of the local heap objects are freed, however, the size of the heap does not automatically shrink. You can recover this area by calling the LocalShrink function. This function first compacts the local heap, and then truncates the automatic data segment to the specified number of bytes. LocalShrink will truncate below neither the highest currently allocated memory object, nor the originally specified heap size.
You can declare the automatic data segment to be fixed or movable in the application's .DEF file, just as you can any data or code segment. Unless you have a good reason to do otherwise, always declare the automatic data segment as movable and multiple. The automatic data segment is always preloaded. The following example shows how to declare the automatic data segment in the .DEF file:
DATA MOVEABLE MULTIPLE
By declaring the application's automatic data segment as movable, you allow Windows to relocate the data segment in memory as its size changes. If the automatic data segment is fixed, Windows increases the size of the local heap only if adjacent memory happens to be available. Consequently, if you declare the automatic data segment to be fixed, you should be careful to specify an adequate initial HEAPSIZE value in the .DEF file.
You should specify the MULTIPLE attribute for DATA to provide a separate automatic data segment for each instance of your application. Only dynamic-link libraries can be declared with the SINGLE attribute for DATA. In fact, dynamic-link libraries must be declared this way, since they can have only one instance each.