问题
I have narrowed down a memory leak to the following code
CFStringRef CFDataToString(CFDataRef data)
{
UInt8* buf = malloc(CFDataGetLength(data));
CFDataGetBytes(data, CFRangeMake(0, CFDataGetLength(data)), buf);
CFMutableStringRef output = CFStringCreateMutable(kCFAllocatorDefault, CFDataGetLength(data) * 2);
for(int i = 0; i < CFDataGetLength(data); i++) {
CFStringAppendFormat(output, NULL, CFSTR("%02x"), buf[i]);
}
free(buf);
CFRelease(data);
return output;
}
Below is the code used in context, some methods has been simplified for demonstration. Instruments is reporting a memory leak of CFStringCreateMutable and CFStringAppendFormat.
CFStringRef CFDataToString(CFDataRef data)
{
UInt8* buf = malloc(CFDataGetLength(data));
CFDataGetBytes(data, CFRangeMake(0, CFDataGetLength(data)), buf);
CFMutableStringRef output = CFStringCreateMutable(kCFAllocatorDefault, CFDataGetLength(data) * 2);
for(int i = 0; i < CFDataGetLength(data); i++) {
CFStringAppendFormat(output, NULL, CFSTR("%02x"), buf[i]);
}
free(buf);
CFRelease(data);
return output;
}
CFDataRef hmac(CFStringRef key, CFStringRef data)
{
const char *cKey = CFStringGetCStringPtr(key, CFStringGetSystemEncoding());
const char *cData = CFStringGetCStringPtr(data, CFStringGetSystemEncoding());
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
CFDataRef HMAC = CFDataCreate(kCFAllocatorDefault, cHMAC, sizeof(cHMAC));
return HMAC;
}
CFDictionaryRef buildRequest(CFMutableDictionaryRef params)
{
CFMutableStringRef signature = CFStringCreateMutable(NULL, 0);
CFStringAppend(signature, CFDataToString(hmac(CFSTR("mykey"), CFSTR("mydata"))));
CFDictionarySetValue(params, CFSTR("signature"), signature);
// ....
// ....
return params;
}
void request(CFMutableDictionaryRef params)
{
params = buildRequest(params);
// ... Run request
CFRelease(params);
}
Instruments output...
回答1:
Just once more as answer.
All data allocated with a Create method puts the responsibility for releasing the data to the programmer. In this regard, it's the same as calling malloc. No method will ever release this data, unless explicitely stated in the documentation.
To solve your problem, save a reference to the 'Created' (Allocated) data in the method which receives it and release it at the end of the method, once you're done with it.
来源:https://stackoverflow.com/questions/14967275/cfstring-memory-leak