У меня есть цикл for
который я динамически устанавливаю объект при использовании указателя. Я хотел бы использовать один и тот же указатель для следующего экземпляра, но я беспокоюсь, что происходит утечка памяти.
myPointer *obj;
for (int i = 0; i <= 10; i++) {
obj = new Object(i);
obj->doSomeStuff();
}
Должен ли я установить obj в NULL
в конце инструкции for
? delete obj
только, кажется, вызывает серьезные проблемы в этом случае.
Изменение: я добавил метод сброса для класса, чтобы сбросить значения частных переменных, чтобы выполнить другой проход. Кажется, он работает немного лучше/быстрее.
Все, что вы new
вам нужно delete
или просочится его.
Object* obj;
for (int i = 0; i <= 10; i++) {
obj = new Object(i);
obj->doSomeStuff();
delete obj;
}
В противном случае, как только наступит следующая итерация, вы Object
new
Object
, назначьте его указателю obj
, а предыдущий объект просочится.
В этом случае вам даже не нужен указатель, если вы не хотите беспокоиться об управлении памятью самостоятельно.
for (int i = 0; i <= 10; i++) {
Object obj {i};
obj.doSomeStuff();
} // Now obj will fall out of scope and be automatically cleaned up.
Установка указателя на NULL
обеспечивает утечку памяти, так как теперь нет способа delete
объект allcoated. Если delete obj
вызывает проблемы, вам необходимо исправить эти проблемы, иначе у вас будет утечка памяти. (Если объект каким-то образом не удаляет себя.)
Чтобы добавить, new Object(i);
создает новый неназванный Object
в куче, пространство в памяти, которое вам, как программисту, доверено управлять.
С obj = new Object(i);
вы храните дескриптор объекта, записывая его местоположение в памяти, то есть его адрес в указателе obj
, который является тем, что указатели хранят.
Затем код переходит во второй цикл и перезаписывает записанное местоположение в obj
с местоположением new Object(i)
.
Теперь вы потеряли местоположение первого Object
. Поскольку вы не знаете, где это, вы не можете его очистить, что приводит к утечке памяти.
Как и в примере с Cyber, все эти беспорядочные вещи с кучей можно избежать, просто создав вместо этого стек. Стек - это память, которая управляется для вас. Вы можете прочитать об этом здесь.
Теперь, если вы настаиваете на использовании указателей и распределении по куче, вам нужно научиться очищаться после себя, как и все остальные здесь.
Идея, снова упомянутая Cyber, заключается в том, чтобы delete
каждый new
который у вас есть. Чтобы delete
что-то, вам нужно его местоположение, поэтому вам понадобится указатель, чтобы запомнить его местоположение до его удаления.
Вам также понадобится правильный тип, чтобы мы могли знать, насколько большой фрагмент памяти мы должны delete
. Обратите внимание на то, что ваш указатель другого типа от объекта, который вы пытаетесь удалить.
Также, пожалуйста, не ошибайтесь, что указатели работают только с кучей. Они также работают с объектами в стеке.
Object obj(10);
Object obj2(20);
Object* pointer_to_obj = &obj; //address of obj
pointer_to_obj = &obj2; //Now store the address of obj2
Надеюсь, я помог вам.
PS Установка obj
, указатель на NULL
или nullptr
(С++ 11) в основном означает, что указатель не сохраняет местоположение какого-либо объекта.
На самом деле в этом случае правильным было бы удалить указатель ИЛИ вы закончите утечку памяти.
myPointer *obj;
for (int i = 0; i <= 10; i++) {
obj = new Object(i);
obj->doSomeStuff();
delete obj;
}