GlobalReAlloc() and GMEM_ZEROINIT ClarifiedLast reviewed: July 23, 1997Article ID: Q92942 |
3.00 3.10
WINDOWS
kbprg
The information in this article applies to:
SUMMARYGlobalReAlloc() is documented in the Windows API's reference manuals. This is a clarification of one of the flags you can set for GlobalReAlloc(). Under one circumstance, when GlobalReAlloc() is used with GMEM_ZEROINIT, it may not zero out all of the reallocated memory. This situation occurs when GlobalReAlloc() is called to shrink a block of memory and then enlarge it.
MORE INFORMATIONWhen GlobalReAlloc() is used with GMEM_ZEROINIT to increase the size of a block of memory in the global heap, it will zero out only the bytes it adds to the memory object; it does not initialize any of the memory that existed before the call. Windows allocates memory from the global heap in multiples of 32 bytes; enhanced mode allocates memory on even 32-byte boundaries, and standard mode allocates memory on odd 32-byte boundaries (that is, /E allocates 32/64/96 bytes, /S allocates 16/48/80 bytes).Thus, when 10 bytes are requested, enhanced Windows actually allocates 32 bytes; when 55 bytes are requested, enhanced Windows allocates 64 bytes. Suppose we have the following sequence of calls in Windows enhanced mode: HGLOBAL hMem ;
// 32 bytes are actually allocated, not 10 because Windows // allocates global memory in multiples of 32 bytes. All // 32 bytes are initialized to zero.hMem = GlobalAlloc(GMEM_ZEROINIT | GMEM_FIXED, 10);
// Here, we allocate 32 more bytes and add them to the end of // the first 32 bytes. ReAllocating to 40 bytes will cause the // block to be 64 bytes long. Only the second 32 // bytes are initialized to zero. The first 32 bytes are left // alone.hMem = GlobalReAlloc(hMem, 40, GMEM_ZEROINIT | GMEM_FIXED);
// Copy 39 bytes into the memory block. The first 39 bytes // will contain the string.lstrcpy((LPSTR)GlobalLock(hMem), "This is a big enough string for our job")
// Now we shrink the block to 10 bytes. After the call, the // block will be 32 bytes long; the second 32 bytes are freed // and will no longer exist. The first 32 bytes will still // contain the same characters as before the call.hMem = GlobalReAlloc(hMem, 10, GMEM_ZEROINIT | GMEM_FIXED) ;
// Now, we enlarge the block back to 40 bytes. After the call, // the block will be 64 bytes long, and the second 32 bytes // will be initialized to zero. The first 32 bytes will be left // alone, however. The area between bytes 10 and 32 does *not* // get initialized!hMem = GlobalReAlloc(hMem, 40, GMEM_ZEROINIT | GMEM_FIXED) ; When GlobalReAlloc() is called to shrink the block, we told it that we wanted only 10 bytes; that's all we should use. Then when we enlarge it back to 40 bytes, GlobalReAlloc() only initializes the memory it adds to the current block--which is from bytes 33 to 64. The bytes between 10 and 40 were previously used, but GlobalReAlloc() did not initialize them because it did not allocate them. As a result, applications that call GlobalReAlloc() to shrink and then re- enlarge a block of previously used data should not expect that all the bytes will be initialized to zero.
|
Additional reference words: 3.00 3.10
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |