15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


AW: Problem with GlobalFree

Friedrich Hotz -- fritz@nuernberg.netsurf.de
Saturday, September 14, 1996

It is not a good style to use GlobalAlloc in an MFC program. Since MSVC 2.0 we
finally reached the desirable situation to be able to use new/delete overall.

Using malloc and new together in a program cann cause unpredictable results
(see Scott Meyers, "Effective C++ programming").

So, just recode the thing!

----------
Von: 	Olivier Courtois[SMTP:Olivier.Courtois@di.epfl.ch]
Gesendet: 	Donnerstag, 12. September 1996 17:43
An: 	mfc-l@netcom.com
Betreff: 	Problem with GlobalFree

Environment: Windows 95, VC++ 4.0

        Few times ago, I developped a MFC app,  that should now include
a  
part of code taken out from an older app that I didn't create.
        In my part, I used new and delete with CObjet and there was no
memory
leaks, but it turns out to be, that there is now problems with the other
part.
        
        That code uses GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,...)
and
GlobalLock() to allocate memory, but it seems that the GlobalFree()
function is unable to free it.
        First I  think that the memory was not properly unlocked. So I
tested
the LockCount (before using GlobalFree)  with the GlobalFlags function,
and it returns 0 for the lockcount!
        The GlobalFree simply fails and the return value is (as it
should be)
equal to the handle of the global memory object. 

        Could that problem be linked with the fact that I used MFC' new
and
delete in other parts of my programm? How could I solve it?

        Any idea will be appreciated.
                        Thanks
-- 
OO=====================OO=============================OO===================OO
||    _/_/_/ _/_/_/    || Olivier.Courtois@di.epfl.ch
||                   ||
||   _/  _/ _/     _/\ || EPFL-DI-LSP                 ||  Smile,
tomorrow  ||
||  _/  _/ _/     _/ _\|| http://diwww.epfl.ch/w3lsp/ ||      is
worse.    ||
|| _/_/_/ _/_/_/ _/    ||                            
||                   ||
OO=====================OO=============================OO===================OO






Rob Tessier -- Rob_Tessier@iacnet.com
Friday, September 20, 1996

[Mini-digest: 3 responses]

oh contrare,

GloabalAlloc in MFC 4.1 and up allocs memory from the Window's heap.  memory 
alloced via new, malloc, and embedded objects are alloc'd from your 
application's process heap. 

Since your process's heap is optimized more for new/malloc where smaller allocs 
are performed, you can save larger allocs for GlobalAlloc or create your own 
heap via HeapCreate.  Best not to mix large and small allocs into the same heap 
as you end up with fragmentation like your disk drive.

-Rob Tessier

-----------

>It is not a good style to use GlobalAlloc in an MFC program. Since MSVC 2.0 we
>finally reached the desirable situation to be able to use new/delete overall.

>Using malloc and new together in a program cann cause unpredictable results
>(see Scott Meyers, "Effective C++ programming").

>So, just recode the thing!

----------
Von:  Olivier Courtois[SMTP:Olivier.Courtois@di.epfl.ch]
Gesendet:  Donnerstag, 12. September 1996 17:43
An:  mfc-l@netcom.com
Betreff:  Problem with GlobalFree

Environment: Windows 95, VC++ 4.0

        Few times ago, I developped a MFC app,  that should now include
a  
part of code taken out from an older app that I didn't create.
        In my part, I used new and delete with CObjet and there was no
memory
leaks, but it turns out to be, that there is now problems with the other
part.
        
        That code uses GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,...)
and
GlobalLock() to allocate memory, but it seems that the GlobalFree()
function is unable to free it.
        First I  think that the memory was not properly unlocked. So I
tested
the LockCount (before using GlobalFree)  with the GlobalFlags function,
and it returns 0 for the lockcount!
        The GlobalFree simply fails and the return value is (as it
should be)
equal to the handle of the global memory object. 

        Could that problem be linked with the fact that I used MFC' new
and
delete in other parts of my programm? How could I solve it?

        Any idea will be appreciated.
                        Thanks
-- 
OO=====================OO=============================OO===================OO
||    _/_/_/ _/_/_/    || Olivier.Courtois@di.epfl.ch
||                   ||
||   _/  _/ _/     _/\ || EPFL-DI-LSP                 ||  Smile,
tomorrow  ||
||  _/  _/ _/     _/ _\|| http://diwww.epfl.ch/w3lsp/ ||      is
worse.    ||
|| _/_/_/ _/_/_/ _/    ||                            
||                   ||
OO=====================OO=============================OO===================OO


 

-----From: Jerry Coffin 

At 09:51 AM 9/14/96 +0200, you wrote:
>It is not a good style to use GlobalAlloc in an MFC program. 

That depends - especially on Win 3.x, it can be nearly unavoidable.  (E.g.
if you have objects on the heap, and want to allocate some memory that's DDE
sharable.  The former needs to use new, the latter needs GlobalAlloc.)

>Since MSVC 2.0 we
>finally reached the desirable situation to be able to use new/delete overall.
>
>Using malloc and new together in a program cann cause unpredictable results

Not really true.  There's one basic rule to follow: you simply have to keep
the allocation and deallocation matched up - if you get something with new,
you must use delete to release it.  If you get it with malloc, you must use
free to release it.  If you allocate it with GlobalAlloc, you must use
GlobalFree to release it.  As long as you keep things matched up, everything
works fine.

-----From: kyork@tgv.com (k.york)

Uh, as long as you do not delete something that was malloc'd, or free
something that was new'd, both sets of allocators should work fine without
crashing into each other (aka causing unpredictable results). Otherwise one
would not be able to use many of the standard C library functions (strdup,
any of the FILE functions, etc) which would be a bad thing.

As for the original GlobalAlloc/GlobalFree problem, i would guess there is
some subtle error which simply hasn't been noticed until now. I would
suggest using a commercial product such as BoundsChecker.

best o' luck
--kyle



Mike Blaszczak -- mikeblas@nwlink.com
Monday, September 23, 1996

[Mini-digest: 2 responses]

At 10:40 9/20/96 -0400, Rob Tessier wrote:
>GloabalAlloc in MFC 4.1

No, no no NO!

>oh contrare,

Non non non, mais non!

Let me repeat myself: NO!

GlobalAlloc() is an API function.  It doesn't have anything to do with
MFC.  GlobalAlloc() works with or without MFC.  It doesn't change depending
on which version of MFC you're using.  It changes depending on which
version of _Windows(tm) the operating system_ you're using.

>and up allocs memory from the Window's heap. 

By definition: see the Win32 or Win16 API references.  (Period!
It doesn't matter which 3-rd party memory manager you're using, 
or which class library you're using, or even which language you're
using: a call to GlobalAlloc() is a call to the operating system.)

>alloced via new, malloc, and embedded objects are alloc'd from your 
>application's process heap. 

That, on the other hand, really depends on which compiler and
runtime library you're using.  And it depends on which _version_ of
those tools you're using, too.

>Since your process's heap is optimized more for new/malloc
>where smaller allocs are performed, you can save larger allocs
>for GlobalAlloc or create your own heap via HeapCreate. 
>Best not to mix large and small allocs into the same heap 
>as you end up with fragmentation like your disk drive.

All I can say to this is: no, you're wrong.


.B ekiM
http://www.nwlink.com/~mikeblas/
Don't look at my hands: look at my _shoulders_!
These words are my own. I do not speak on behalf of Microsoft.

-----From: Mike Blaszczak 

This part of the note was not attributed to a particular author.
That's good, since I'm normaly considered "a prick" for
telling people when their answers are actualy wrong: I
obviously can't complain about anyone in particular here!

>>It is not a good style to use GlobalAlloc in an MFC program.

That's absolutely wrong.  Period!

You can call GlobalAlloc() whenver you want to.  It's downright
necessary, in some circumstances.  My response to you isn't
a matter of "style": it's a matter of _fact_.

>Since MSVC 2.0 we finally reached the desirable situation 
>to be able to use new/delete overall.

I'm not sure I'd agree with that.

Look: new (malloc/calloc) and delete (free) are general-purpose
routines. They might break badly, or at a minimum, provide less
performance than you want, in some certain situations.  That's
something you'll need to decide for yourself, based on the
situation you're in.

>>Using malloc and new together in a program cann cause
>>unpredictable results (see Scott Meyers,
>>"Effective C++ programming"). 

There's three possible truths here:

a) Scott Meyers is dead-down wrong
b) Actually, Scott Meant that:

   char* pstr = new char[1024];
   free(pstr);

is a bad idea.  That is, mixing C allocators and
C++ releasers (or vise-versa) is bad, but only
over _the same allocation_.
c) You're quoting Scott Meyers incorrectly.

My money parlayed between b) and c).  (And, as 
t turns out, I'm the Jimmy The Greek of C++ programming.)

>>So, just recode the thing!

If you clap your hands and really beleive, you can fly!

But, back on Earth:

a) you might not have time to "recode the thing"
b) you might not _need_ to "recode the thing"

.B ekiM
http://www.nwlink.com/~mikeblas/
Don't look at my hands: look at my _shoulders_!
These words are my own. I do not speak on behalf of Microsoft.




John Addis -- jaddis@erols.com
Monday, September 23, 1996

Friedrich Hotz wrote:
> 
> It is not a good style to use GlobalAlloc in an MFC program. Since MSVC 2.0 we
> finally reached the desirable situation to be able to use new/delete overall.

Really? Exactly how do you use "new" to allocate data for OLE Uniform
Data Transfer (Clipboard/D&D)?
 
> Using malloc and new together in a program cann cause unpredictable results
> (see Scott Meyers, "Effective C++ programming").

Using "malloc" and "new" together can cause a problem -- if you forget
which one you called to allocate what. I fail to see how this applies to
GlobalAlloc/Lock/Free. You could certainly get into trouble if you tried
to call delete on a pointer returned by GlobalLock but I don't think
this is the case here.

> ----------
> Von:    Olivier Courtois[SMTP:Olivier.Courtois@di.epfl.ch]
> Gesendet:       Donnerstag, 12. September 1996 17:43
> An:     mfc-l@netcom.com
> Betreff:        Problem with GlobalFree
> 
> Environment: Windows 95, VC++ 4.0
> 
>         That code uses GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,...)
> and
> GlobalLock() to allocate memory, but it seems that the GlobalFree()
> function is unable to free it.
>         First I  think that the memory was not properly unlocked. So I
> tested
> the LockCount (before using GlobalFree)  with the GlobalFlags function,
> and it returns 0 for the lockcount!

The lock count isn't particularly important, actually. GlobalFree will
free a block of memory regardless of the lock count. You probably won't
even notice unless you happen to be running with a debug kernel.

>         The GlobalFree simply fails and the return value is (as it
> should be)
> equal to the handle of the global memory object.
> 
>         Could that problem be linked with the fact that I used MFC' new
> and
> delete in other parts of my programm? How could I solve it?

I seriously doubt if it has to do with your use of new/delete elsewhere.
Many programs use new/delete and GlobalAlloc/Free. As I indicated
before, anything using the Clipboard or OLE Drag & Drop pretty much
*has* to use global memory for storage.

However... if it is possible to modify the code to use new/delete then
be all means do so. The debug new operator provided with MFC goes a long
way towards tracking down pesky memory bugs. If you can't change ( or
would rather fight than switch)then approach it like any other memory
bug. 

1) What does GetLastError() return?
(To moderator: This seems to be a particularly difficult thing for
people to do. You might consider adding this as part of the standard
'header' blurb. It seems that almost nobody includes this information,
even though it is almost always relevant. Just my $.02)

2) when you are attempting to free the data -- check to see that the
contents of the memory block are what you expect. If they're not you may
be able to learn something from what actually IS in there.

3) track down all the places where the memory block is accessed. Is
there anything funky going on here?

-- 
John Addis        Master of Time and Space
jaddis@erols.com  C++, MFC, Win32, Win95, TCP/IP
"Invalid or missing REALITY.COM Universe halted."




| Вернуться в корень Архива |