Я пытаюсь перечислить локальных пользователей на Mac os. Он работает правильно, но я думаю, что есть некоторая утечка ресурсов. Я не могу этого понять. Профилирование говорит, что утечек памяти нет, но использование памяти постоянно растет (диаграмма отчета о памяти на XCode). В моем случае с 2.7M до 4.9M (5 * 1000 итераций). Может кто-нибудь сказать, что не так с моим кодом. Существуют ли какие-либо утечки или нормальное поведение?
Это простой инструмент инструмента командной строки c++ с кодом Objective-c с настройками построения по умолчанию (XCode 5):
/////////////////////////////////////////////
// main.cpp
#include "test.h"
#include <iostream>
#include <thread>
int main(int argc, const char * argv[])
{
//for (int i = 0; i < 1000; ++i)
for (int i = 0; i < 5; ++i)
{
std::cout << "Iteration # " << i << std::endl;
for (int j = 0; j < 1000; ++j)
{
Execute();
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return 0;
}
/////////////////////////////////////////////
// test.mm
#import <Collaboration/Collaboration.h>
#import <CoreServices/CoreServices.h>
#import <Foundation/Foundation.h>
#import <SystemConfiguration/SCDynamicStore.h>
#import <SystemConfiguration/SCDynamicStoreCopySpecific.h>
#include <iostream>
void Execute()
{
CSIdentityAuthorityRef identityAuthority = CSGetLocalIdentityAuthority();
if (!identityAuthority)
{
std::cout << "Failed to get identity authority." << std::endl;
return;
}
CSIdentityQueryRef usersQuery(CSIdentityQueryCreate(nil, kCSIdentityClassUser, identityAuthority));
if (!usersQuery)
{
std::cout << "Failed to create query." << std::endl;
return;
}
/////////////////////////////////////////////////
// Without CSIdentityQueryExecute(usersQuery, 0, nil) - everething is ok.
/////////////////////////////////////////////////
if (!CSIdentityQueryExecute(usersQuery, 0, nil))
{
std::cout << "Failed to execute query." << std::endl;
return;
}
CFRelease(usersQuery);
}
#ifndef __MY_TEST_H__
#define __MY_TEST_H__
void Execute();
#endif
Я просто запускал эту программу, и я не вижу роста памяти. Я немного упростил его как программу с одним файлом C++ (в настоящее время это сочетание C++ и Obj C++).
У вас есть ошибка памяти, но я бы только ожидал, что это вызовет утечку, если вы получите ошибки. Этот блок утечки запроса:
if (!CSIdentityQueryExecute(usersQuery, 0, nil))
{
std::cout << "Failed to execute query." << std::endl;
return;
}
Вы не должны возвращаться сюда (вам это не требуется), или вы должны включить CFRelease(usersQuery)
перед возвратом. Но опять же, если это была проблема, вы увидите много сообщений журнала "Не удалось выполнить запрос".
Попробуйте выполнить CFRelease
перед каждым return
поскольку некоторые итерации не освобождают данные.
CSIdentityAuthorityRef
? Или, может быть, вы можете попытаться выполнитьCFRelease
перед каждым возвращением. (Я не знаю, это просто идея)