CFString memory leak

天大地大妈咪最大 提交于 2019-12-11 13:43:09

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!