Parmanoir

Managing C Memory with Cocoa, 2

I've been missing the obvious :)
void* malloc_autorelease(size_t size)
{
	void*	p = malloc(size);
	[NSData dataWithBytesNoCopy:p length:size freeWhenDone:YES];
	return	p;
}

And allocate your temporary data with :

	// Allocate
	element* myTempData = malloc_autorelease(sizeof(element)*elementCount);

	// And that's it ! Don't care about freeing, NSData will do it for us
Thanks to Jonathan Wight for the dataWithBytesNoCopy:length:freeWhenDone: tip.

Dmitry Chestnykh
2008 08 12

Now, I like this solution, because it's readable :)

Keith Lazuka
2008 08 12

-[NSData dataWithBytesNoCopy:length:freeWhenDone] does not return void. It returns an NSData object that frees its buffer when it is dealloc'd. Since you throw away that NSData object, your implementation will never free the allocated buffer.

Keith Lazuka
2008 08 12

Whoops! You're right. Of course I go re-read your post after I submitted my comment. As long as there's an autorelease pool in scope, it will work. Sorry!

Russell Finn
2008 08 12

Great tip, but I'm puzzled by one thing: isn't dataWithBytesNoCopy:p length:size freeWhenDone:YES equivalent to simply dataWithBytesNoCopy:p length:size? Or is there some subtle point I'm missing?

Patrick Geiller
2008 08 12

@Russell I've gone back reading NSData's doc and indeed both are equivalent. I didn't know dataWithBytesNoCopy:length: freed its pointer, its variant dataWithBytesNoCopy:length:freeWhenDone: apparently exists to create an NSData that will not free the pointer.

So dataWithBytesNoCopy:length: will work just as well !

Patrick Geiller
2008 08 13

Thanks Rainer !

I did Google 'malloc autorelease' before writing that post, without finding anything relevant. I need to level up my Google-fu …

Jon Hohle
2008 09 01

This has the odd side effect of the malloc'd memory being deallocated when the nearest autorelease pool as opposed to an explicit free. Since you're not returning the NSData* there is no way to retain the value for use later.

If you're method returned an NSData, you could still get at the element

NSData* tempData = malloc_autorelease(sizeof(element) * elementCount);
element* myTempData = (element*) [tempData bytes];
[tempData retain];
...
[tempData release];
Patrick Geiller
2008 09 01

Not caring when the memory is released is exactly the point :)

The lifetime of malloc_autorelease memory is the same as autoreleased objects like [NSURL URLWithString:…] and serves the same purpose : use some data now and don't care when it's freed, thanks to dataWithBytesNoCopy that will do it for us.


Follow me on Twitter
Planet Cocoa
Cocoa.fr

2011 02 22Distance field
2010 07 202Binding through NSApp
2010 05 122Forwarding invocations
2010 02 272Core Image black fringes
2010 02 21Quickest Way to Shell
2010 02 08Who's calling ?
2009 09 2138 ways to use Blocks in Snow Leopard
2009 08 182Bracket Mess
2009 08 124Taming JavascriptCore within and without WebView
2009 04 15Debugging with Activity Monitor
2009 03 25How Core Image Color Tracking works
2009 03 1510Custom NSThemeFrame
2009 03 10Which framework is running ?
2009 03 074CoreUI can paint pretty big
2009 02 18Localization with functions
2009 01 30Did you forget to nest alloc and init?
2009 01 16JSCocoa on the iPhone
2009 01 11Mixing WebView and JavascriptCore
2009 01 09Badge overflow
2009 01 09Find your Garbage Collection leaks with Instruments

Powered by MediaWiki