Question

I am using the libical library to parse the iCalendar format and read the information I need out of it. It is working absolutely fine so far, but there is one odd thing concerning ical. This is my code:

icalcomponent *root = icalparser_parse_string([iCalData cStringUsingEncoding:NSUTF8StringEncoding]);

if (root)
{    
    icalcomponent *currentEvent = icalcomponent_get_first_component(root, ICAL_VEVENT_COMPONENT);

    while (currentEvent)
    {    
        while(currentProperty)
        {    
            icalvalue *value = icalproperty_get_value(currentProperty);
            char *icalString = icalvalue_as_ical_string_r(value); //seems to leak
            NSString *currentValueAsString = [NSString stringWithCString:icalString
                                                                encoding:NSUTF8StringEncoding];
            icalvalue_free(value);
            //...
            //import data
            //...
            icalString = nil;
            currentValueAsString = nil;
            icalproperty_free(currentProperty);
            currentProperty = icalcomponent_get_next_property(currentEvent, ICAL_ANY_PROPERTY);
        } //end while
    } //end while
    icalcomponent_free(currentEvent);
}
icalcomponent_free(root);

//...

I did use instruments to check my memory usage and were able to find out, that this line seems to leak:

char *icalString = icalvalue_as_ical_string_r(value); //seems to leak

If I'd copy and paste this line 5 or six times my memory usage would grow about 400kb and never get released anymore.

There is no free method for the icalvalue_as_ical_string_r method because it's returning a char *..

Any suggestions how to solve this issue? I would appreciate any help!

EDIT

Taking a look at the apple doc says the following:

To get a C string from a string object, you are recommended to use UTF8String. This returns a const char * using UTF8 string encoding.

const char *cString = [@"Hello, world" UTF8String];

The C string you receive is owned by a temporary object, and will become invalid when automatic deallocation takes place. If you want to get a permanent C string, you must create a buffer and copy the contents of the const char * returned by the method.

But how to release a char * string properly now if using arc? I tried to add @autorelease {...} in front of my while-loop but without any effort. Still increasing memory usage...

Was it helpful?

Solution

Careful with the statement "no free method...because it's returning a char*"; that is never something you can just assume.

In the absence of documentation you can look at the source code of the library to see what it does; for example:

http://libical.sourcearchive.com/documentation/0.44-2/icalvalue_8c-source.html

Unfortunately this function can do a lot of different things. There are certainly some cases where calling free() on the returned buffer would be right but maybe that hasn't been ensured in every case.

I think it would be best to request a proper deallocation method from the maintainers of the library. They need to clean up their own mess; the icalvalue_as_ical_string_r() function has at least a dozen cases in a switch that might have different deallocation requirements.

OTHER TIPS

icalvalue_as_ical_string_r returns a char * because it has done a malloc() for your result string. If your pointer is non-NULL, you have to free() it after use.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top