Удалить объект, на который указывает

0

У меня есть цикл for который я динамически устанавливаю объект при использовании указателя. Я хотел бы использовать один и тот же указатель для следующего экземпляра, но я беспокоюсь, что происходит утечка памяти.

myPointer *obj;
for (int i = 0; i <= 10; i++) {
    obj = new Object(i);
    obj->doSomeStuff();
}

Должен ли я установить obj в NULL в конце инструкции for? delete obj только, кажется, вызывает серьезные проблемы в этом случае.

Изменение: я добавил метод сброса для класса, чтобы сбросить значения частных переменных, чтобы выполнить другой проход. Кажется, он работает немного лучше/быстрее.

  • 0
    Вы должны описать «серьезные проблемы». Это не точное описание.
  • 0
    Почему вы хотите выделить динамически? И почему вы хотите повторно использовать этот же указатель для следующего экземпляра?
Показать ещё 1 комментарий
Теги:
memory-leaks
iteration

4 ответа

5

Все, что вы 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.
  • 1
    Есть неизбежно некоторые исключения. Если obj-> doSomeStuff () передает право собственности на this в другой контейнер, поток или обратный вызов API, который требует, чтобы время жизни объекта было расширено за пределы вызова функции, удаление его напрямую, как описано, было бы плохо.
  • 0
    Каков будет контекст передачи параметров в объект?
Показать ещё 1 комментарий
2

Установка указателя на NULL обеспечивает утечку памяти, так как теперь нет способа delete объект allcoated. Если delete obj вызывает проблемы, вам необходимо исправить эти проблемы, иначе у вас будет утечка памяти. (Если объект каким-то образом не удаляет себя.)

1

Чтобы добавить, 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) в основном означает, что указатель не сохраняет местоположение какого-либо объекта.

0

На самом деле в этом случае правильным было бы удалить указатель ИЛИ вы закончите утечку памяти.

myPointer *obj;
for (int i = 0; i <= 10; i++) {
    obj = new Object(i);
    obj->doSomeStuff();
    delete obj;
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню