Ответ 1
Нет, этот код в порядке и не будет утечки памяти.
Вам нужно использовать только delete [] один раз, потому что вы использовали только одно новое для выделения области памяти, хотя в эту же память есть два указателя.
char *pointer1;
char *pointer2;
pointer1 = new char[256];
pointer2 = pointer1;
delete [] pointer1;
Другими словами, нужно ли мне делать delete [] pointer2
?
Спасибо!
Нет, этот код в порядке и не будет утечки памяти.
Вам нужно использовать только delete [] один раз, потому что вы использовали только одно новое для выделения области памяти, хотя в эту же память есть два указателя.
Простое правило: вам нужно столько delete
, что есть new
s. Еще лучше, используйте что-то вроде умного указателя или контейнера, чтобы позаботиться о нем для вас.
И еще одна второстепенная точка: pointer2
становится "висящим указателем", когда вы вызываете delete
на pointer1
.
Это не утечка, но она просит неприятностей. pointer2
указывает на who-know-what, как только вы удаляете pointer1
. Это то, что называется "свисающим указателем". Использование его в лучшем случае может привести к segfault, а в худшем случае может привести к таинственным искажениям данных во всем, что в конечном итоге выделяет то же место.
В то время как это не утечка памяти, если вы хотите быть явным, вы должны установить как point1
, так и point2
в NULL (и инициализировать их таким же образом.)
Кроме того, рассмотрите возможность использования 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 в основном промежуточной областью для расширений для С++.
delete
удаляет память, выделенную new
. Поскольку у вас есть только один new
, вам нужен только один delete
.
Используйте только Удалить, когда вы использовали New
Хорошей практикой является установка указателя2 в NULL, но у вас не будет утечки памяти, если вы не
Нет, вам не нужно удалять [] указатель2, потому что вы не выделили для него память!
Оператор pointer2 = pointer1
указывает, что pointer2
указывает на тот же адрес памяти, что и pointer1
, не выделяет для него дополнительной памяти.
Каждый new
должен иметь один и только один, соответствующий delete
. Если вы удалили другой указатель, вы нарушите это правило.
Что вы здесь делаете, просто скажите, что блок памяти, выделенный new char[256]
, будет указывать на pointer1
и pointer2
в тот же момент.
Это будет утечка памяти, если вы напишете инструкцию delete[] pointer2;
после.
Здесь пробел в вашем мышлении: вы не удаляете указатели - вы удаляете память. Вы просто используете указатель, чтобы идентифицировать освобожденный блок памяти. Поскольку две переменные указывают на одну и ту же память, удаление одного из них точно эквивалентно удалению другого. Другими словами, удаление обоих - это то же самое, что удаление одного из них дважды - что явно неверно.