Search code examples
objective-ccocoansdata

dataWithBytesNoCopy:length: memory management


I am using dataWithBytesNoCopy:length: method for creating NSData object from bytes.

-(NSData *)dataFromBytes
{ 
...
   void *data = malloc(bytes);
... 
    return [NSData dataWithBytesNoCopy:data length:bytes];;
}

From apple documentation:

The returned object takes ownership of the bytes pointer and frees it on deallocation.

should i release return data object in caller function?

-(void)testFunction
{
NSAutoreleasePool *nsp = [[NSAutoreleasePool alloc] init];

NSData *ldata = [mObject dataFromBytes];
NSlog(@"%@", ldata)//printing data
[nsp release];
NSlog(@"%@", ldata)//Not printing data //sometimes getting exc_bad_access

}

Solution

  • Short answer: No, the caller should only release the returned data if it has retained it. In your testFunction you haven't retained it so you shouldn't release it.

    Longer answer: Firstly, the dataFromBytes method in your above code doesn't have a return value, presumably this should actually return NSData *.

    Anyway, the dataWithBytesNoCopy:length: method returns an autoreleased NSData instance which is immediately being returned from the method. We know that it is autoreleased because the method name doesn't contain init, new or copy. This means the caller is NOT automatically taking ownership of the returned data so it shouldn't release it (unless it retains it).

    Ownership of the data that has been malloc'ed is taken over by the NSData object and shouldn't be freed. When the NSData instance is dealloc'ed it will free the memory that was malloc'ed.

    In your, testFunction you are receiving the NSData object and printing it. Next you release the autorelease pool which will cause the autoreleased object to be released and dealloc'ed. You print it again but it has already been dealloc'ed which is dangerous (I'm surprised it doesn't always EXC_BAD_ACCESS.