char *pointer1;
char *pointer2;
pointer1 = new char[256];
pointer2 = pointer1;
delete [] pointer1;
Другими словами, должен ли я также делать delete [] pointer2
?Это утечка памяти?
Спасибо!
char *pointer1;
char *pointer2;
pointer1 = new char[256];
pointer2 = pointer1;
delete [] pointer1;
Другими словами, должен ли я также делать delete [] pointer2
?Это утечка памяти?
Спасибо!
Нет, этот код в порядке и не будет утечки памяти.
Вам нужно использовать только delete [] один раз, потому что вы использовали только одно новое для выделения области памяти, даже если в эту же память есть два указателя.
Правильно. Фактически вы ** не должны ** - попытка «удалить» один и тот же блок памяти дважды приведет к неопределенному поведению. –
Следует также отметить, что любая попытка отклонения «указатель2» также приведет к неопределенному поведению. –
сторона .. Как вы учитесь .. Я бы сказал, что неплохо установить указатель1 = NULL; Как рефлекс для удаления. Я видел кучу кода, где указатель удален, но позже приложение выполняет if (pointer1) .. – baash05
использовать только удалить, когда вы использовали New
Хорошо PRACTIVE это установить pointer2 в NULL, но не будет иметь место утечка памяти, если вы не
delete
удаляет память, которая была выделено new
. Поскольку у вас есть только один new
, вам нужен только один delete
.
Простое правило: вам нужно столько delete
s, сколько есть new
s. Еще лучше, используйте что-то вроде умного указателя или контейнера, чтобы позаботиться о нем для вас.
И еще один второстепенный момент: pointer2
становится «оборванным указателем», как только вы позвоните delete
по телефону pointer1
.
Заметьте, что указатель1 также становится свисающим указателем после удаления ... –
Очень верно, но я думал, что это было более очевидно :) –
Нет, вам не нужно удалять [] указатель2, потому что вы не выделили для него память!
Заявление pointer2 = pointer1
делает pointer2
указывает на тот же адрес памяти, что и pointer1
, не выделяет дополнительную память для него.
Um ... 'pointer2' указывает на тот же адрес * как *' pointer1', он делает не указывать на адрес 'pointer1' (адрес' pointer1' будет '& pointer1'. –
@Nathan Ernst: Извините, я ошибся. Исправлено – nico
Каждый new
должен иметь один и только один, соответствующий delete
. Если вы удалите другой указатель, вы нарушите это правило.
Что вы здесь делаете, просто скажите, что блок памяти, выделенный new char[256]
, будет указывать pointer1
и pointer2
в тот же момент.
Это была бы утечка памяти, если вы написали заявление delete[] pointer2;
.
Это было бы неопределенное поведение, если он удалил указатель 2. На практике я не знать одну платформу, где это приведет к утечке памяти. Скорее всего, вы получите что-то вроде segfault/AV. –
Хотя это не утечка памяти, если вы хотите быть явным, вы должны установить как point1
и point2
на NULL (и инициализировать их таким образом тоже.)
Это не утечка, но она просит для беспокойства. pointer2
указывает, кто знает, что только вы удалите pointer1
. Это то, что называется «свисающим указателем». Использование его в лучшем случае может привести к segfault, а в худшем случае может привести к таинственным искажениям данных во всем, что в конечном итоге выделяет то же место.
Вот пробел в вашем мышлении: вы не удаляете указатели - вы удаляете память. Вы просто используете указатель, чтобы идентифицировать освобожденный блок памяти. Поскольку две переменные указывают на одну и ту же память, удаление одного из них точно эквивалентно удалению другого. Другими словами, удаление обоих - это то же самое, что удаление одного из них дважды - что явно неверно.
Кроме того, рассмотрите возможность использования 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<>
себя.
Я настоятельно рекомендую использовать библиотеки Повысьте эффективность как много Как это написано pro, это в основном промежуточная область для расширений C++.
Как правило, # из 'delete''s should обычно соответствуют # из 'новых'. – Amber
Вы не удаляете указатели, вы удаляете то, на что указывают. – immibis