mah
mah

Reputation: 39797

True leak or false analyzer report?

I have code that looks like the following:

CFDictionaryRef myFunction()
{
    CFIndex myNumberIndex = 1234;
    CFNumberRef myNumber = NULL;
    CFMutableDictionaryRef theDict =  CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 0, 0);

    myNumber = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &myNumberIndex);
    CFDictionaryAddValue(theDict, kSomeKeyConstant, myNumber);

    return theDict;
}

The clang static analyzer reports that myNumber is a leaked object. Obviously since there's no call to CFRelease() I'm inclined to understand the issue, but I'm not well versed enough with CF in general so I want to verify: does myNumber need to be released here even though it's added to a CFDictionary that gets returned? That is... is what I'm adding to the dictionary a copy having its own retain/release needs (in which case I do need to release it here)? I assume the answer has to do with the kCFAllocatorDefault parameter used when the dictionary was created but I don't see a clear indication of ownership of the object.

Upvotes: 2

Views: 188

Answers (1)

Caleb
Caleb

Reputation: 124997

does myNumber need to be released here even though it's added to a CFDictionary that gets returned?

Yes, you need to release it. If the dictionary wants to retain that object, it will -- what the dictionary does with it isn't your problem. But you created the object, so you need to release it.

It might help to look at the issue from the perspective of the function that calls myFunction(). myFunction() returns a CFDictionary. Is the caller supposed to release every object in that dictionary when it no longer needs the dictionary? Of course not. But if the caller doesn't do it, and if you don't release myNumber, the object will never be released, right? That's a leak.

See the Core Foundation memory management rules for further explanation. One of the examples there is nearly the same situation and shows the release being performed as required:

float myFloat = 10.523987;
CFNumberRef myNumber = CFNumberCreate(kCFAllocatorDefault,
                                    kCFNumberFloatType, &myFloat);
CFMutableArrayRef myArray = CFArrayCreateMutable(kCFAllocatorDefault, 2, &kCFTypeArrayCallBacks);
CFArrayAppendValue(myArray, myNumber);
CFRelease(myNumber);

Upvotes: 3

Related Questions