Перезапись переменной, инициализированной новым ключевым словом c ++

0

Если я сделаю что-то вроде:

void foo() {
  bar* b2 = new bar();
  b2 = new bar();
}

Что происходит с первым значением строки, инициализированным new? Переписывается ли оно вторым назначением или удаляется с помощью ключевого слова delete заранее?

  • 9
    Нет, первый экземпляр bar жив, но потерян. Это называется «утечка памяти». Все, что вы делаете, это указывает указателю b2 на новую переменную.
Теги:
delete-operator
new-operator

5 ответов

3
Лучший ответ

Вы должны вызвать delete для первого b2 прежде чем назначать новое значение b2. Второй вызов действительно перезапишет значение в b2 (которое является адресом объекта, созданного в первом new).

Другими словами, ваш код имеет утечку памяти, потому что первый объект bar "потерян".

4

Это утечка памяти. C++ выделил место для вашего объекта, а затем вы потеряли все ссылки на него, поэтому он будет сидеть там, пока остальная часть ваших программ не будет бесполезной и голодной.

Поэтому в C++ обычно предпочитают не использовать new.

void foo() {
  bar b2 = bar();
  b2 = bar();
}

особенно в ситуациях, когда вы хотите использовать переменную только в 1 области, выделение ее в стеке является гораздо более безопасным выбором. Особенно в случае исключений

Foo foo = new Foo();
...
delete foo;

небезопасно, что, если ... выдает исключение? Тебя утечка! Если вы хотите использовать семантику безопасности и указателя в C++ 11

unique_ptr<bar> b2;

если вам действительно нужна семантика указателя. Теперь, когда все ссылки на b2 будут потеряны, он удаляется сам. Примечание. Циклы все еще не сломаны и не протекают.

  • 0
    Вы должны хотя бы объяснить альтернативу использования классов-оболочек для интеллектуальных указателей, чтобы люди знали, что вы имеете в виду, когда говорите «предпочтительно не использовать новые».
  • 0
    @ LB-- Обновлено :)
0

Если вы создаете что-то с new вы должны освободить его с удалением, иначе утечка памяти будет там. Чтобы предотвратить утечку, вы должны написать:

void foo() {
  bar* b2 = new bar();
  delete b2;
  b2 = new bar();
}
0

В вашей первой строке есть три "вещи".

  1. определите переменную b2 типа bar *,
  2. выделять объект панели в кучу новым оператором
  3. присвойте результат 2 переменной, определенной в 1

Учитывая это разделение, очевидно, что вы назначаете два значения по одной переменной. Поскольку вам нужна эта переменная, чтобы удалить объект, который вы потеряли после перезаписи первого назначенного значения. Это одна из ситуаций "утечки памяти".

Перед вами перезаписать переменную b2, вы должны думать о первом экземпляре объекта класса bar. Если это больше не требуется, используйте delete для удаления объекта. Если вам все еще нужно, сделайте копию указателя.

0

Ваша первая строка:

bar* b2 = new bar() будет выделять комнату sizeof(bar) в свободном хранилище (а также вызвать конструктор) и дать вам адрес этого устройства, скажем, 0x123, это означает, что b2 запоминает 0x123.

Но теперь вы перезаписываете свой b2 - теперь он указывает на новое местоположение, данное вам новым. Это означает, что вы больше не можете связаться с более старым блоком памяти, который был назначен первым новым вызовом.

Ещё вопросы

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