Skip navigation.
 
mlRe: Where's the buffer overrun?
FROM : Michael Ash
DATE : Thu Mar 20 17:00:29 2008

On Thu, Mar 20, 2008 at 2:58 AM, Jean-Daniel Dupas
<<email_removed>> wrote:
>
>  Le 20 mars 08 à 06:26, Michael Ash a écrit :
>
>  > On Thu, Mar 20, 2008 at 12:56 AM, Jens Alfke <<email_removed>>
>  > wrote:
>  >> It's never a good idea to
>  >> make assumptions about where a Foundation object is putting its data;
>  >> if you need to access the current bytes of an NSData, call -bytes
>  >> on it.
>  >
>  > This was a little confusing to me until I thought about it a bit, so I
>  > thought I would emphasize this.
>  >
>  > When you use these methods and tell it to free the memory, the object
>  > you create takes ownership of the block of memory. This means that
>  > it's responsible for freeing it, but more importantly it means that
>  > it's *in control* of freeing it. In other words, conceptually speaking
>  > it's never safe to refer back to this block of memory directly after
>  > you create the object. Instead you should query the object to get
>  > whatever you need from it, in this case query the -bytes method to get
>  > the pointer back.
>  >
>  > If I understand the API contract, the code in question is not even
>  > safe when using NSData. It happens to work, but the contract does not
>  > guarantee it. To be safe, the NSData should be created, then the
>  > return value from its -bytes method should be returned. If I'm wrong
>  > about this, I'd appreciate any corrections.
>
>  -bytes returns a (const void *) that you should not change.
>  If you want to create a raw buffer using NSData, use NSMutableData and
>  -mutableBytes method.


That's right. Using NSMutableData is better, but inefficient, since as
we noted it will copy your block. If you want to return an
"autoreleased" pointer without a copy then I believe there are two
approaches:

- Malloc the memory, build its contents, and only when you're done
wrap it in an NSData. This will require you to return a const pointer
but that's probably preferable anyway. The fact that it doesn't copy
is, of course, an implementation detail but since it's just for
efficiency's sake then nothing terrible will happen if this detail
changes.

- Simply allocate the block using +[NSMutableData dataWithLength:] in
place of malloc. This will give you a pre-wrapped piece of mutable
memory which you can modify and return.

Personally the last approach seems best to me, it's simple and
obvious. It should probably be noted that none of these approaches
will work under garbage collection, but the answer there is of course
even easier, just use NSAllocateCollectable and be done with it.

Mike

Related mailsAuthorDate
mlWhere's the buffer overrun? Nick Zitzmann Mar 20, 00:38
mlRe: Where's the buffer overrun? Chris Suter Mar 20, 00:50
mlRe: Where's the buffer overrun? Andrew Farmer Mar 20, 01:00
mlRe: Where's the buffer overrun? Hamish Allan Mar 20, 01:03
mlRe: Where's the buffer overrun? Nick Zitzmann Mar 20, 01:04
mlRe: Where's the buffer overrun? Chris Suter Mar 20, 01:18
mlRe: Where's the buffer overrun? Hamish Allan Mar 20, 01:49
ml[SOLVED] Re: Where's the buffer overrun? Nick Zitzmann Mar 20, 02:20
mlRe: Where's the buffer overrun? stephen joseph but… Mar 20, 02:22
mlRe: Where's the buffer overrun? Nick Zitzmann Mar 20, 02:31
mlRe: Where's the buffer overrun? Chris Suter Mar 20, 02:42
mlRe: Where's the buffer overrun? Hamish Allan Mar 20, 02:46
mlRe: Where's the buffer overrun? Jens Alfke Mar 20, 05:56
mlRe: Where's the buffer overrun? Michael Ash Mar 20, 06:26
mlRe: Where's the buffer overrun? Jean-Daniel Dupas Mar 20, 07:58
mlRe: Where's the buffer overrun? Hamish Allan Mar 20, 09:42
mlRe: Where's the buffer overrun? Michael Ash Mar 20, 17:00