iOS - libical / const char * - использование памяти

Я использую библиотеку libical для синтаксического анализа формата iCalendar и считывания необходимой мне информации. Пока он работает абсолютно нормально, но есть одна странная вещь в отношении ical. Это мой код:

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);

//...

Я использовал инструменты для проверки использования памяти и смог выяснить, что эта строка, похоже, протекает:

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

Если бы я скопировал и вставил эту строку 5 или 6 раз, мое использование памяти увеличилось бы приблизительно на 400 КБ и никогда больше не было бы освобождено

Там нет бесплатного метода для icalvalue_as_ical_string_r метод, потому что он возвращает символ *..

Любые предложения, как решить эту проблему? Буду признателен за любую помощь!

РЕДАКТИРОВАТЬ

Взглянув на Apple Doc, говорит следующее:

Чтобы получить строку C из строкового объекта, рекомендуется использовать UTF8String. Это возвращает const char * с использованием строкового кодирования UTF8.

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

Полученная вами строка C принадлежит временному объекту и станет недействительной, когда произойдет автоматическое освобождение. Если вы хотите получить постоянную строку C, вы должны создать буфер и скопировать содержимое const char *, возвращаемого методом.

Но как правильно выпустить строку char * сейчас, если использовать дугу? Я пытался добавить @autorelease {...} перед циклом while, но без каких-либо усилий. Все еще увеличивается использование памяти...

2 ответа

Решение

Осторожнее с утверждением "нет бесплатного метода... потому что он возвращает символ *"; это никогда не то, что вы можете просто предположить.

В отсутствие документации вы можете посмотреть на исходный код библиотеки, чтобы увидеть, что она делает; например:

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

К сожалению, эта функция может делать много разных вещей. Конечно, в некоторых случаях free() на возвращенном буфере было бы правильно, но, возможно, это не было обеспечено в каждом случае.

Я думаю, что было бы лучше запросить правильный метод освобождения от сопровождающих библиотеки. Им нужно навести порядок в собственном беспорядке; icalvalue_as_ical_string_r() функция имеет по крайней мере десяток случаев в switch это может иметь разные требования освобождения.

icalvalue_as_ical_string_r возвращает char * потому что он сделал malloc() для вашей строки результата. Если ваш указатель не равен NULL, вы должны освободить его () после использования.

Другие вопросы по тегам