Memory and Pointers

To be portable, source code must avoid any techniques that rely on the 16-bit segment**:**offset address structure, because all pointers are 32 bits in size under Win32 and use flat rather than segmented memory.

This difference in pointer structure is usually not a problem unless the code uses HIWORD, LOWORD, or similar macros to manipulate portions of the pointer.

For example, in Windows 3.x, memory is allocated to align on a segment boundary, which makes memory allocation functions return a pointer with an offset of 0x0000. The following code exploits this fact to run successfully under Windows 3.x:

ptr2 = ptr1 = malloc();               // ptr2 = xxxx:0000
LOWORD( ptr2 ) = index * elementsize; // Place offset of array element
                                      //   into ptr2 low word

Such code does not work properly under Win32. But standard pointer constructs, such as the following, always result in portable code:

ptr1 = malloc();         // Set ptr1 to start of memory block
ptr2 = &ptr1[i];         // Place offset of array element

Here are some other guidelines for dealing with pointers:

  • All pointers, including those that access the local heap, are 32 bits under Win32.

  • Addresses never wrap, as they can with the low word in segmented addressing. For example, in Windows 3.x, an address can wrap from 1000:FFFF to 1000:0000.

  • Structures that hold near pointers in Windows 3.x must be revised because all pointers are 32 bits in Win32. This may affect code that uses constants to access structure members, and it may also affect alignment.