C 字符串内存泄漏

C 字符串内存泄漏,c,memory-leaks,core-foundation,C,Memory Leaks,Core Foundation,我已将内存泄漏的范围缩小到以下代码 CFStringRef CFDataToString(CFDataRef data) { UInt8* buf = malloc(CFDataGetLength(data)); CFDataGetBytes(data, CFRangeMake(0, CFDataGetLength(data)), buf); CFMutableStringRef output = CFStringCreateMutable(kCFAllocatorD

我已将内存泄漏的范围缩小到以下代码

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;
}    
CFStringRef CFDataToString(CFDataRef数据)
{
UInt8*buf=malloc(CFDataGetLength(data));
CFDataGetBytes(数据,CFRangeMake(0,CFDataGetLength(数据)),buf);
CFMutableStringRef输出=CFStringCreateMutable(kcfolocatorDefault,CFDataGetLength(数据)*2);
对于(int i=0;i
下面是上下文中使用的代码,一些方法已简化以供演示。 Instruments报告内存泄漏为CFStringCreateMutableCFStringAppendFormat

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);
}
CFStringRef CFDataToString(CFDataRef数据)
{
UInt8*buf=malloc(CFDataGetLength(data));
CFDataGetBytes(数据,CFRangeMake(0,CFDataGetLength(数据)),buf);
CFMutableStringRef输出=CFStringCreateMutable(kcfolocatorDefault,CFDataGetLength(数据)*2);
对于(int i=0;i
仪器输出


请再说一次作为答案

使用
Create
方法分配的所有数据将负责向程序员发布数据。在这方面,它与调用
malloc
相同。除非在文档中明确说明,否则任何方法都不会发布此数据


要解决您的问题,请在接收“已创建”(已分配)数据的方法中保存对该数据的引用,并在使用完该数据后在方法末尾释放该数据。

您将在何处释放已分配的数据?我相信大家还记得,CFStringCreate…创建字符串,一旦使用完,必须通过“CFRelease”释放字符串。CFDataToString在“CFStringAppend”中“消失”,而不被释放。将指针保存在某个位置,并在附加后释放它。这就是问题所在,创建一个指向CFDataToString返回的CFStringRef的指针,然后在附加到签名后释放CFStringRef可以解决内存泄漏问题。我以为
CFStringAppend
释放了传递给它的字符串。也许可以看看这个[CFString内存泄漏][1][1]: