Rules for Using Far Pointers to Memory Objects

Last reviewed: August 12, 1997
Article ID: Q77473

The information in this article applies to:

  • Microsoft Windows Software Development Kit (SDK) for Windows versions 3.0 and 3.1

In Windows version 3.0 standard and enhanced modes, rules for using far pointers have been relaxed substantially. This is due to the use of the protected mode of the 80286, 80386, and 80486 processors. In this mode, far pointers are no longer a segment:offset value. Protected mode far pointers are made up of a selector:offset value. The selector is an index into a descriptor table. Each descriptor contains information about a block of memory, such as size, location in memory (linear memory if in enhanced mode, physical memory if in standard mode), and access rights. For more information on the descriptor table, refer to Chapter 3 of "The 80386/80486 Programming Guide" by Ross P. Nelson (Microsoft Press).

The protected mode of the 80286, 80386, and 80486 processors allows memory blocks to be moved in memory without invalidating their selector:offset value. This is accomplished by changing the reference to the location in memory in the descriptor rather than changing the actual selector value.

Because of this functionality, using far pointers in standard and enhanced modes is much easier. In the following four circumstances, far pointers to data can be assumed to be valid:

  1. Global memory that is allocated with GlobalAlloc() as movable and nondiscardable

    The far pointer returned from GlobalLock() can be assumed to be valid as long as the GlobalUnlock() function has not been called. Once GlobalUnlock() has been called, the far pointer can no longer be assumed to be valid because the memory may be discarded. However, the far pointer will remain valid in the case of memory that is nondiscardable and is not an automatic data segment. Because of the selector technology discussed above, movable memory can move without invalidating the far pointer.

    NOTE: If a block is reallocated using GlobalReAlloc() and the new size requires a different number of selectors (for example 50K reallocated to 110K or 65K reallocated to 63K), the base selector value may be changed. Each selector can refer to a maximum of 64K of memory.

  2. Far pointers to static or global data within an application

    Static and global data within an application is stored in the static data area of the application's DGROUP. Because the whole DGROUP segment is moved, the far pointer will still be valid after a move in protected mode.

  3. Automatic data within a function as long as that function has not been exited

    Far pointers to automatic data will be valid as long as no return has been executed from the function that allocated the data. Automatic data is stored on the stack. When an application returns from a function, the memory allocated by that function is no longer allocated and cannot be assumed to be valid. This then makes memory that a far pointer references subject to corruption.

  4. Local memory that has been locked with LocalLock()

    Memory allocated with LocalAlloc() comes from the local heap. Memory on the local heap can be moved around within the DGROUP segment, which will cause the offset value of its location to change. This will invalidate any far pointers to the memory. The LocalLock() function fixes the memory within the local heap.

For compatibility with future versions of Windows, far pointers to data within an application should NEVER be passed to other applications. The current version of Windows uses one LDT (local descriptor table) for all descriptors associated with data. In the future, one LDT may be used for each application's data, while a GDT (global descriptor table) may be used for shared data. If a selector:offset combination from one application is used in another application in such an environment, the selector will be used to reference a descriptor in the called application's LDT. The descriptor in the called application's LDT will most likely not contain the correct reference for the memory block. The only supported way to share data between applications is global memory allocated with the GMEM_SHARE (also known as the GMEM_DDESHARE) flag.

Selectors that are aliased, using AllocDStoCSAlias() or AllocSelector(), will not be updated when the memory is moved. For this reason, far pointers that include aliased selectors cannot be assumed to be valid unless the memory has been fixed into place with GlobalFix().

For a more detailed description of memory management under protected mode and Windows 3.0, see Chapters 17 and 18 of "Peter Norton's Windows 3.0 Power Programming Techniques." This book is available from Bantam Computer Books and is coauthored by Paul Yao.

KBSubcategory: KrMm

Keywords          : kb16bitonly KrMm kbhowto
Version           : 3.0 3.1
Platform          : WINDOWS
Issue type        : kbhowto


================================================================================


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: August 12, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.