Считайте, что у меня есть функция:
int &create_ptr(){
int *x = new int;
*x =5;
return *x;
}
int main(){
int y = create_ptr();
}
Это приведет к утечке памяти или есть как-то ее удалить?
Извините, если это основной вопрос, это просто беспокоило меня, и я не мог найти ответ.
Спасибо всем, теперь имеет смысл!
Чтобы удовлетворить ваше любопытство, да, вы можете delete
это безопасно, но только если вы вернете его по ссылке (указатель или ссылка C ++ (&
)). По ссылке, чтобы сохранить первоначальный адрес вашего new
под ред. Вам нужен этот адрес, чтобы вы правильно и безопасно delete
ваш объект.
int& create_ref(){
int *x = new int;
*x =5;
return *x;
}
int* create_ptr(){
int *x = new int;
*x =5;
return x;
}
int create_sane_version() {
return 5;
}
int main(){
int& x = create_ref();
delete &x; // OK. Get address of x; same as deleting through a pointer pointing to its address
// x here refers to the newed object inside create_ref() (*x)
// Still begs the question of why you're painstakingly doing this
int* y = create_ptr();
delete y; // OK, but not optimal (the above isn't either)
// * not optimal == a bad way to do this
int leak = create_ref();
delete &leak; // DEFINITELY NOT OK. leak isn't the same as the newed object
// i.e. &leak != &create_ref();
// You're actually *copying* the object referred to by the returned
// reference. The returned reference gets lost.
int best_way_to_do_this = create_sane_version();
}
Это приведет к утечке памяти?
Да, это будет. Вы выделяете динамическую память с new
заявление без соответствующего delete
чтобы освободить его, значит, у вас утечка памяти.
Есть ли как-то его удалить?
Конечно, есть: не делайте динамическое распределение памяти с голыми указателями. В вашем случае, зачем вам вообще нужна ссылка?
int create(){
return 5;
}
int main(int, char*[]){
int y = create();
}
Если вам действительно нужна динамическая память, вы можете использовать std::shared_ptr
а также std::make_shared
как это:
#include <memory>
auto create_ptr() {
return std::make_shared<int>(5);
}
int main(int, char*[]) {
std::shared_ptr<int> y = create_ptr();
}
Да, это приведет к утечке памяти. Вы выделяете пространство с new
, но никогда не освобождай его, используя delete
,
Если вы хотите создать объект (или тип примитива) в бесплатном хранилище, вы можете вернуть указатель и вызвать функцию вызова для удаления указанного объекта.
// Caller is responsible for deleting pointed-to int.
int* create_ptr()
{
// Hope that operator new does not throw std::bad_alloc
int* x = new int;
*x = 5;
return x;
}
Лучшим подходом было бы вернуть умный указатель, но он выходит за рамки этого вопроса.
Так как вы создаете память в куче int * x = new int;, вам необходимо явно удалить ее.
Вы можете использовать общие указатели, если хотите избежать отслеживания всей памяти кучи и удаления ее явно.
Общие указатели отслеживают все ссылки на память, когда последняя ссылка выходит из области видимости, указанная память удаляется.