Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Creating a Handle from an existing memory




On Jun 12, 2007, at 4:43 AM, Yaron Tadmor wrote:

If you look at various packages supplying memory management, some allow
you to pass your own memory and even your own deallocation method. For
example, boost:share_ptr.

Boost is not part of the OS. I'm not aware of any part of the Mac OS that can release your C++ objects for you if they were allocated with new. Furthermore, let's suppose such an API exists. What is supposed to happen in the last line of the following:


Char *myP = new char[100];
Handle myH = MemoryToHandle (myP, 100);
SetHandleSize( myH, 200 ); // <-- what happens here?

Or better yet:

CThing *myP = new CThing();
Handle myH = MemoryToHandle (myP, sizeof( CThing ) );
SetHandleSize( myH, 2 * sizeof( CThing ) ); // <-- what happens here?

Now you need to provide allocation and deallocation functions. Messy. Very messy IMO.

If you want resizable memory and you're using C++, use a vector.

By default, when reference counting drops to
0, it calls c++ delete on the object. But you could very well pass a
deleter object which does something else.

So it's perfectly fine to assume such a MemoryToHandle function can be
available,

Not really:

- If it were available it would be in MacMemory.h. Since there is no such API in MacMemory.h and no such API is documented anywhere, it's actually perfectly fine to assume such a function does *not* exist. ;-) Furthermore, it should be obvious that they wouldn't have added such functionality in Carbon (see below for why it's obvious to me).

- The code you provided:

Handle myH = MemoryToHandle (myP, 100);

didn't have any provision for specifying how the memory should or should not be released. The function you describe in your discussion above is reasonable; the one to which I was responding was not.

- Resizing such a handle would be problematic. Handles are not just allocated and released, they are also resizable. Would you have the Memory Manager simply return an error if you tried to resize one of these handles?

marking that handle as a "no delete" handle. Meaning that
when it's released, the memory is not to be deleted, and deletion should
be handled by the user. Carbon has quite a few examples of such things.

Yes, but there have been no new APIs introduced for creating handles in Carbon (or for many years before that ;-), and if there were, they'd be in MacMemory.h with all the other basic handle APIs.


They *could* have introduced such APIs (although they would involve issues such as I describe above), but handles are very much a Mac thing that exist to facilitate having blocks of memory that can move to avoid memory fragmentation. Since this need has essentially disappeared in Mac OS X and Apple encourages developers to use malloc and new to allocate memory, I'm sure they saw little or no value in enhancing the Memory Manager to do the kind of thing you describe. Now that Mac OS X is based on Unix some of the old Mac-specific technologies are pretty much only supported to provide legacy support for applications using them.

For example, some CF creation APIs let you specify an deallocator. You can specify kCFAllocatorMalloc, in which case CF will release the memory for you, but you can't specify a deallocator for memory allocated with NewPtr. I'm sure the old Memory Manager is considered legacy technology by the people driving Mac OS X. It hasn't been deprecated and may never be deprecated, but I'd be very surprised if they ever do anything to enhance any of it.

And as a test, I tried using PtrToHand and PtrToXHand, passing my c++
allocated memory instead of a real Ptr allocated by the system. Guess
what.... It worked!!! Releasing the handle, did not try to delete the
memory, as I would expect.

Of course it worked. Both of these APIs allocate a new block of memory or resize the existing memory and copy the data to it. A pointer allocated by new is a valid pointer and any valid address will work with these APIs. You can even use the address of a stack variable to copy its contents to a handle:


Rect		r = { 0,0,100,100 };
Handle	h;
err = PtrToHand( &r, &h, sizeof( Rect ) );

In all cases disposing of the handle will release the handle's memory, but not the original, which the Memory Manager ignores once it's been copied.

So, yes, I've been programming long enough to know such questions are
certainly in place.

Matter of perspective. ;-) From my perspective, everything from the lack of such an API in MacMemory to the various issues I mention about make it unreasonable to expect the existence of such an API.


Now, all that said, the only value I could see in this it if you need to pass something to an old API that expects a handle and you don't want to copy data, but the right answer there is for Apple to provide new APIs that accept pointers.

Larry
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Carbon-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/carbon-dev/email@hidden

This email sent to email@hidden
References: 
 >RE: Creating a Handle from an existing memory (From: "Yaron Tadmor" <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.