Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

GlobalAlloc: why use GlobalLock???

935 views
Skip to first unread message

Jim

unread,
Jan 5, 2003, 3:41:45 PM1/5/03
to
Looking at the following code taken from MSDN library I can't understand why
the GlobalAlloc call is followed by a GlobalLock. What is the need for a
GlobalLock call? Can anyone shed some light on this?
#define BUFFER 4096

HINSTANCE hinst; // handle of current instance
HWND hwndSubclass; // handle of a subclassed window
HANDLE hIcon, hCursor;
HGLOBAL hMem;
char *lpMem;
TCHAR tchPath[] = "c:\\winnt\\samples\\winprop.c";

// Load resources.

hIcon = LoadIcon(hinst, MAKEINTRESOURCE(400));
hCursor = LoadCursor(hinst, MAKEINTRESOURCE(220));

// Allocate and fill a memory buffer.

hMem = GlobalAlloc(GPTR, BUFFER);
lpMem = GlobalLock(hMem);
lstrcpy(lpMem, tchPath);
GlobalUnlock(hMem);

// Set the window properties for hwndSubclass.

SetProp(hwndSubclass, "PROP_ICON", hIcon);
SetProp(hwndSubclass, "PROP_CURSOR", hCursor);
SetProp(hwndSubclass, "PROP_BUFFER", hMem); Jim


Lucian Wischik

unread,
Jan 5, 2003, 3:50:20 PM1/5/03
to
Jim <jim.o...@jimbo.com> wrote:
>Looking at the following code taken from MSDN library I can't understand why
>the GlobalAlloc call is followed by a GlobalLock. What is the need for a
>GlobalLock call? Can anyone shed some light on this?

GlobalAlloc merely allocates space, but it doesn't yet exist as a chunk of
memory at any specified location. GlobalLock is what pins it down to one
specific location, so allowing you to write into it.

--
Lucian Wischik, Queens' College, Cambridge CB3 9ET. www.wischik.com/lu

Matti Vuori

unread,
Jan 5, 2003, 3:59:55 PM1/5/03
to
ljw...@cus.cam.ac.uk (Lucian Wischik) wrote in
news:ava5qc$pdt$1...@pegasus.csx.cam.ac.uk:

> Jim <jim.o...@jimbo.com> wrote:
>>Looking at the following code taken from MSDN library I can't
>>understand why the GlobalAlloc call is followed by a GlobalLock. What
>>is the need for a GlobalLock call? Can anyone shed some light on this?
>
> GlobalAlloc merely allocates space, but it doesn't yet exist as a
> chunk of memory at any specified location. GlobalLock is what pins it
> down to one specific location, so allowing you to write into it.

Well, MSDN says this about GlobalLock: "This function is provided only for
compatibility with 16-bit versions of Windows."

The way I see it, it is used for historical reasons and because it
explicitly converts a HGLOBAL to a pointer type.

--
Matti Vuori, <http://sivut.koti.soon.fi/mvuori/index-e.htm>

Jim

unread,
Jan 5, 2003, 4:01:37 PM1/5/03
to
> GlobalAlloc merely allocates space, but it doesn't yet exist as a chunk of
> memory at any specified location. GlobalLock is what pins it down to one
> specific location, so allowing you to write into it.

Why then the following code:

pbih = (PBITMAPINFOHEADER) pbi;
lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);

if (!lpBits)
errhandler("GlobalAlloc", hwnd);

// Retrieve the color table (RGBQUAD array) and the bits
// (array of palette indices) from the DIB.
if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi,
DIB_RGB_COLORS))
{
errhandler("GetDIBits", hwnd);
}

Why isn't GlobalLock called in this situation with the handle from the
GlobalAlloc call used immediately???

Jim

Lucian Wischik

unread,
Jan 5, 2003, 4:16:28 PM1/5/03
to
Matti Vuori <mvu...@koti.soon.fi> wrote:
>> GlobalAlloc merely allocates space, but it doesn't yet exist as a
>> chunk of memory at any specified location. GlobalLock is what pins it
>> down to one specific location, so allowing you to write into it.
>Well, MSDN says this about GlobalLock: "This function is provided only for
>compatibility with 16-bit versions of Windows."

Heh, that'll teach me to write replies without first having read the MSDN
article on it. Ignore what I said, and pay attention to what Matti says :)

Damian Driscoll

unread,
Jan 5, 2003, 5:31:25 PM1/5/03
to

"Jim" <jim.o...@jimbo.com> wrote in message
news:R21S9.78375$R45.3...@news2.tin.it...

<quote>
GMEM_FIXED Allocates fixed memory. The return value is a pointer.
GMEM_MOVEABLE Allocates movable memory. In Win32, memory blocks are never
moved in physical memory, but they can be moved within the default heap.
The return value is a handle to the memory object. To translate the handle
into a pointer, use the GlobalLock function.

This flag cannot be combined with the GMEM_FIXED flag.
</quote>

Damian


Tomas Restrepo [MVP]

unread,
Jan 5, 2003, 5:34:21 PM1/5/03
to
Jim,

> Why then the following code:
>
> pbih = (PBITMAPINFOHEADER) pbi;
> lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
>
> if (!lpBits)
> errhandler("GlobalAlloc", hwnd);
>
> // Retrieve the color table (RGBQUAD array) and the bits
> // (array of palette indices) from the DIB.
> if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi,
> DIB_RGB_COLORS))
> {
> errhandler("GetDIBits", hwnd);
> }
>
> Why isn't GlobalLock called in this situation with the handle from the
> GlobalAlloc call used immediately???
>

GlobalLock() is only needed if you are calling GlobalAlloc() with the
GMEM_MOVEABLE flag. If you alloc it with GMEM_FIXED, as done in the code
above, the return value is a direct pointer.

Notice that even in the case of GMEM_MOVEABLE, the poster was incorrect (I
think he was probably thinking of VirtualAlloc()). What happens with this
flag is that the memory is indeed allocated, but the actual memory might be
moved around in the heap, so its actual virtual address could potentially
change during the program's execution. GlobalLock() tells the memory manager
to leave it locked in place for a while.

--
Tomas Restrepo
tom...@mvps.org

Tomas Restrepo [MVP]

unread,
Jan 5, 2003, 6:35:27 PM1/5/03
to
Hi Carl,

> ... except that Win32 OS's never (ever) move blocks around in the heap.
> Everything about GlobalAlloc and friends is really just a holdover from
> Real-Mode 16-bit Windows, where memory blocks could be moved by the OS and
> when so moved, the visible value of the pointer would in fact change.
> Everything since Win3.1 has operated in protected mode, and if blocks are
> ever moved in physical memory, it's done "behind the scenes" and the
> addresses seen by application programs never change.

AFAIK, you're right, but better safe than sorry, I say.
Besides this, notice that I didn't say anything moved in *physical* memory.
I said it could move in the *heap* (which is all virtual memory, anyway).
Potentially, one could conceive GMEM_MOVEABLE could be used to allow heap
compaction, although I doubt it is ever done.

--
Tomas Restrepo
tom...@mvps.org

Carl Daniel [MVP]

unread,
Jan 5, 2003, 6:16:01 PM1/5/03
to
"Tomas Restrepo [MVP]" <tom...@mvps.org> wrote in message
news:OosnVqQtCHA.2484@TK2MSFTNGP10...

> Notice that even in the case of GMEM_MOVEABLE, the poster was incorrect (I
> think he was probably thinking of VirtualAlloc()). What happens with this
> flag is that the memory is indeed allocated, but the actual memory might
be
> moved around in the heap, so its actual virtual address could potentially
> change during the program's execution. GlobalLock() tells the memory
manager
> to leave it locked in place for a while.

.... except that Win32 OS's never (ever) move blocks around in the heap.


Everything about GlobalAlloc and friends is really just a holdover from
Real-Mode 16-bit Windows, where memory blocks could be moved by the OS and
when so moved, the visible value of the pointer would in fact change.
Everything since Win3.1 has operated in protected mode, and if blocks are
ever moved in physical memory, it's done "behind the scenes" and the
addresses seen by application programs never change.

-cd


Tim Robinson

unread,
Jan 5, 2003, 7:52:12 PM1/5/03
to
Jim <jim.o...@jimbo.com> wrote:
| Looking at the following code taken from MSDN library I can't
| understand why the GlobalAlloc call is followed by a GlobalLock. What
| is the need for a GlobalLock call? Can anyone shed some light on this?

GlobalAlloc and GlobalLock are largely irrelevant. Use malloc or new; if you
can't use those, use HeapAlloc.

The only time you _need_ to use GlobalAlloc is when using IDataObject under
some circumstances, or when using DDE.

--
Tim Robinson, MVP (Windows SDK)
http://www.themobius.co.uk/


Norman Bullen

unread,
Jan 5, 2003, 8:26:00 PM1/5/03
to

In any case, the OP's question regarded GlobalAlloc() used with the GPTR
flag which forces the return value to be a valid pointer. With this flag
GlobalLock() is unnecessary even in Dark Ages Windows.

Norm

Norman Bullen

unread,
Jan 6, 2003, 7:12:45 AM1/6/03
to

Or when putting data on the Clipboard.

Norm

0 new messages