У меня есть функция фу как
myType** foo(){
myType **array = malloc( .... );
//Do some stuff
return array;
}
Здесь я заболел, но не освободил его, как возвращаю. Это приведет к утечке памяти? Должен ли я явно освободить его в вызывающей функции после его использования?
Это утечка памяти, только если вы не освобождаете память (независимо от того, где).
В этом случае вам следует free
это после вызова функции, и вы сделали с указателем.
Но это C-способ сделать это. В C ++ вы возвращаете умный указатель и используете new
вместо malloc
,
С этим типом функции вызывающая сторона является «владельцем» ресурсов, на которые указывает указатель. Таким образом, абонент должен либо освободить ресурсы, либо передать их кому-то другому, кто это сделает.
В C ++ предпочтение отдано возвращению типа, который управляет своими собственными ресурсами, например std::vector
или умный указатель, что оба заботятся о перераспределении ресурсов и проясняют права собственности.
Посмотрите этот пример и не волнуйтесь, прочитайте все о копия elision, в частности оптимизация именованных возвращаемых значений (NRVO).
std::vector<std::vector<SomeType>> foo()
{
std::vector<std::vector<SomeType>> tmp = ....;
// do some stuff
return tmp;
}
Утечки памяти вызваны не освобождения памяти. Пока память будут освободиться в какой-то момент, тогда это не утечка. Но если указатель когда-либо «теряется» или если какой-то цикл зависимости вызывает ситуацию, когда память остается, даже после того, как она перестала быть полезной, то в этот момент вы создали утечку.
Обычно в такой ситуации вы создаете шаблон, подобный следующему:
void* mything_init() {
void *obj = malloc(LEN);
// do some initialization
return obj;
}
void mything_uninit(void* thing) {
// any teardown
free(thing);
}
Для каждого mything
что ты _init
Вы должны в конце концов позвонить _uninit
на этом объекте. Это ваша ответственность как пользователя этой библиотеки. В то время как автор этой библиотеки, вы убедитесь, что все, что вы выделяете в _init
должным образом освобожден в _uninit
,
Это шаблон C, а не шаблон C ++, так как malloc () является идиомой C. C ++ использует new
а также delete
и такую работу мы обычно выполняем в паре конструктор / деструктор.
У меня были проблемы с этой проблемой в течение длительного времени. Я предлагаю вам прочитать эту вики-страницу:
В вашем случае вы можете использовать unique_ptr. Таким образом, вы сможете передать владение указателем функции вызова.
unique_ptr<int> callee1()
{
std::unique_ptr<int> p1(new int(5));
return p1;
}
int main()
{
std::unique_ptr<int> result = callee1() ;
(*result)++; // Increase the value stored in the pointer
std::cout << "New Value: " << (*result) << std::endl;
result.reset() ;
}
Надеюсь, этот код снайпер поможет вам.