Это утечка памяти?

char *pointer1;
char *pointer2;

pointer1 = new char[256];
pointer2 = pointer1;

delete [] pointer1;

Другими словами, нужно ли мне делать delete [] pointer2?

Спасибо!

Ответы

Ответ 1

Нет, этот код в порядке и не будет утечки памяти.

Вам нужно использовать только delete [] один раз, потому что вы использовали только одно новое для выделения области памяти, хотя в эту же память есть два указателя.

Ответ 2

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

И еще одна второстепенная точка: pointer2 становится "висящим указателем", когда вы вызываете delete на pointer1.

Ответ 3

Это не утечка, но она просит неприятностей. pointer2 указывает на who-know-what, как только вы удаляете pointer1. Это то, что называется "свисающим указателем". Использование его в лучшем случае может привести к segfault, а в худшем случае может привести к таинственным искажениям данных во всем, что в конечном итоге выделяет то же место.

Ответ 4

В то время как это не утечка памяти, если вы хотите быть явным, вы должны установить как point1, так и point2 в NULL (и инициализировать их таким же образом.)

Ответ 5

Кроме того, рассмотрите возможность использования boost::shared_ptr<> в библиотеках Boost. Это величайшая вещь, поскольку нарезанный хлеб.

typedef boost::shared_ptr<TypeX> StrRef;

foo() {
  StrRef pointer1(new TypeX);

  while(something) {
    StrRef pointer2 = pointer1;
    // do stuff
  }

 return;
}

Данные (TypeX) будут удалены, если последний указатель на него выходит за пределы области видимости. Вы можете сделать что-то подобное со встроенным типом auto_ptr<>, если вам не нужен счетчик ссылок:

typedef auto_ptr<TypeX> StrRef;

foo() {
  StrRef pointer1(new TypeX);

  while(something) {
    TypeX * pointer2 = pointer1.get();
    subroutine(pointer2);
    if (condition) return;
  }

 return;
}

Всякий раз, когда pointer1 выходит за пределы области видимости, он удаляет данные. Преимущество в этом состоит в том, что вам не нужно помнить о том, чтобы поставить delete перед оператором return внизу, и если pointer1 выходит за пределы области по любой другой причине (т.е. возврат из середины цикла или subroutine() генерирует исключение, то данные все равно будут освобождены.

Я не тестировал этот код, поэтому вам нужно будет проверить документы для auto_ptr<> и boost::shared_ptr<> самостоятельно.

Я настоятельно рекомендую использовать библиотеки Boost как можно больше. Он написан pro pro в основном промежуточной областью для расширений для С++.

Ответ 6

delete удаляет память, выделенную new. Поскольку у вас есть только один new, вам нужен только один delete.

Ответ 7

Используйте только Удалить, когда вы использовали New

Хорошей практикой является установка указателя2 в NULL, но у вас не будет утечки памяти, если вы не

Ответ 8

Нет, вам не нужно удалять [] указатель2, потому что вы не выделили для него память!

Оператор pointer2 = pointer1 указывает, что pointer2 указывает на тот же адрес памяти, что и pointer1, не выделяет для него дополнительной памяти.

Ответ 9

Каждый new должен иметь один и только один, соответствующий delete. Если вы удалили другой указатель, вы нарушите это правило.

Ответ 10

Что вы здесь делаете, просто скажите, что блок памяти, выделенный new char[256], будет указывать на pointer1 и pointer2 в тот же момент.

Это будет утечка памяти, если вы напишете инструкцию delete[] pointer2; после.

Ответ 11

Здесь пробел в вашем мышлении: вы не удаляете указатели - вы удаляете память. Вы просто используете указатель, чтобы идентифицировать освобожденный блок памяти. Поскольку две переменные указывают на одну и ту же память, удаление одного из них точно эквивалентно удалению другого. Другими словами, удаление обоих - это то же самое, что удаление одного из них дважды - что явно неверно.