How do I free() after malloc() when the result of malloc() is returned by the function?

心已入冬 提交于 2021-01-27 19:44:52

问题


I have the following instance method (adapted from Listing 3-6 of the Event Handling section in the iPhone Application Programming Guide):

- (CGPoint)originOfTouch:(UITouch *)touch
{
    CGPoint *touchOriginPoint = (CGPoint *)CFDictionaryGetValue(touchOriginPoints, touch);
    if (touchOriginPoint == NULL)
    {
        touchOriginPoint = (CGPoint *)malloc(sizeof(CGPoint)); // leaks
        CFDictionarySetValue(touchOriginPoints, touch, touchOriginPoint);
        *touchOriginPoint = [touch locationInView:touch.view];
    }
    return *touchOriginPoint;
}

Every once in a while my app leaks 16 Bytes as a result of the call to malloc(). I'm not sure how to return touchOriginPoint while free()ing it as well.


回答1:


If you do not care a minor performance loss, use an NSMutableDictionary and store the point as an NSValue:

NSValue* touchOriginPointValue = [touchOriginPoints objectForKey:touch];
if (touchOriginPointValue == nil) {
   touchOriginPointValue = [NSValue valueWithCGPoint:[touch locationInView:touch.view]];
   [touchOriginPoints setObject:touchOriginPointValue forKey:touch];
}
return [touchOriginPointValue CGPointValue];

If you must use the CFDictionary approach, you have to find a place to free those malloc-ed memory when the values are not needed. Therefore, you have to pass the values callbacks when creating the dictionary

static void free_malloced_memory (CFAllocatorRef allocator, const void *value) {
   free((void*)value);
}
static const CFDictionaryValueCallBacks values_callbacks = {0, NULL, free_malloced_memory, NULL, NULL};
...
touchOriginPoints = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, & values_callbacks);
...



回答2:


If you must return the malloc'd value from the function, then you have passed the responsibility for freeing the memory to the calling function, or one of its callers.

Since we can't see the calling functions, we can't diagnose any more.




回答3:


If you are going to be returning an object that is allocated, then either you need to have the caller free() it, or else you need to be using some kind of garbage collection (so it gets freed automatically).




回答4:


you don't actually return a pointer, the value is copied to a temp value when it is returned, so you aren't really returning the allocation at all, the problem is that you just aren't freeing it either, you add the allocation to the dictionary and just leave it there?

is there like an EndOfTouch function? where you remove the touch from the dictionary? if there is, call free on your allocation there and you should be fine



来源:https://stackoverflow.com/questions/2145152/how-do-i-free-after-malloc-when-the-result-of-malloc-is-returned-by-the-fu

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