Утечка памяти при использовании функции стиля C в Objective C - PullRequest
3 голосов
/ 25 июня 2010

Если я объявлю функцию, такую ​​как:

NSString* createAString(std::string toConvert);

NSString* createAString(std::string toConvert)
{
      return [NSString stringWithUTF8String:toConvert.c_str()];
}

У меня сложилось впечатление, что из-за того, что я не вызвал alloc для строки, она будет находиться в области автоматического выпуска.

Когда я запускаю этот код, детектор утечки памяти XCodes сообщает мне, что с этой точки произошла утечка памяти. Могу ли я не смешивать функции стиля C и типы Objective C таким образом или есть более фундаментальная проблема под рукой?

Приветствие Stubear

Ответы [ 5 ]

2 голосов
/ 26 июня 2010

@ Ответ Юджи мертв, и правильный ответ.

Я просто хотел указать, что вместо того, чтобы сделать эту функцию C, вы можете сделать ее "больше Какао" и использовать категорию:

//NSString+STDConversion.h
@interface NSString (STDConversion)

+ (NSString *) stringWithStdString:(std::string toConvert);

@end

//NSString+STDConversion.mm (note the .mm extension)
@implementation NSString (STDConversion)

+ (NSString *) stringWithStdString:(std::string toConvert) {
  return [NSString stringWithUTF8String:toConvert.c_str()];
}

@end

Теперь в другом месте вы можете сделать:

std::string myString = "This is my string";
NSString * myCocoaString = [NSString stringWithStdString:myString];
2 голосов
/ 26 июня 2010

В вашем коде нет ничего плохого.Вы можете смешивать функции в стиле C в кодах Objective-C.Я не вижу проблем ни с сохранением / выпуском объектов Obj-C, ни с новым / удалением объектов C ++.

Но имя вашей функции нарушает Правило создания .т. е. если имя функции или метода содержит alloc, create или copy, предполагается, что он возвращает объект NSObject или CF с счетом сохранения 1. Статический анализатор XCode работает при условии, что этоправить.Вы также работаете с этим правилом.В противном случае сохранение / выпуск будет испорчено.

Попробуйте Построить и проанализировать этот файл.

#import <CoreFoundation/CoreFoundation.h>

extern CFStringRef FooCreate(void);
int main (int argc, const char * argv[]) {
    CFStringRef string=FooCreate();
    /* CFRelease(string); */
    return 0;
}

Вы можете увидеть результат изменений анализатора, если оставите комментарий (101) *.Вам не нужно предоставлять определение FooCreate.Даже если вы предоставите, текущий анализатор не смотрит на него, а полагается на имя функции.

Ваш код возвращает автоматически высвобождаемую переменную, даже если имя метода содержит create.Это могло бы сбить с толку анализатор и дать ложный положительный результат.

0 голосов
/ 26 июня 2010

Проверьте, не вызываете ли вы это из-за пределов пула (stringWithUTF8String: использует его). Попробуйте обернуть это в

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    //...
[pool drain];

Если это решит проблему, то вы (как вы сказали) вне области действия.

0 голосов
/ 26 июня 2010

Этот код мне подходит.

Вероятно, в другом месте у вас есть код, который неправильно сохраняет эту строку и не освобождает ее позже, что приводит к утечке.XCode не может сказать вам, где происходит несоответствующее сохранение / освобождение, он может только сказать вам, где произошла утечка объекта.

Также, как уже упоминали другие, ваше использование «create» нарушает правила именования Objective-C,Вы должны переименовать это в stringFromStdString или что-то подобное.Для получения бонусных баллов вы можете сделать это расширением класса NSString.

0 голосов
/ 25 июня 2010

Возвращаемая вами строка будет автоматически освобождена, но как насчет строки (C ++), которую вы передаете методу?Освободите ли вы это потом?

Еще одна вещь, которая приходит мне в голову, это то, что LLVM, компилятор, который используется для выполнения статического анализа, еще не поддерживает C ++ (по крайней мере, в публично выпущенной версии).Это может быть просто ложным срабатыванием, потому что он не полностью понимает часть кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...