2010-05-17 2 views
13
char *pointer1; 
char *pointer2; 

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

delete [] pointer1; 

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

Спасибо!

+27

Как правило, # из 'delete''s should обычно соответствуют # из 'новых'. – Amber

+0

Вы не удаляете указатели, вы удаляете то, на что указывают. – immibis

ответ

17

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

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

+12

Правильно. Фактически вы ** не должны ** - попытка «удалить» один и тот же блок памяти дважды приведет к неопределенному поведению. –

+4

Следует также отметить, что любая попытка отклонения «указатель2» также приведет к неопределенному поведению. –

+0

сторона .. Как вы учитесь .. Я бы сказал, что неплохо установить указатель1 = NULL; Как рефлекс для удаления. Я видел кучу кода, где указатель удален, но позже приложение выполняет if (pointer1) .. – baash05

0

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

Хорошо PRACTIVE это установить pointer2 в NULL, но не будет иметь место утечка памяти, если вы не

1

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

7

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

И еще один второстепенный момент: pointer2 становится «оборванным указателем», как только вы позвоните delete по телефону pointer1.

+2

Заметьте, что указатель1 также становится свисающим указателем после удаления ... –

+0

Очень верно, но я думал, что это было более очевидно :) –

0

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

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

+0

Um ... 'pointer2' указывает на тот же адрес * как *' pointer1', он делает не указывать на адрес 'pointer1' (адрес' pointer1' будет '& pointer1'. –

+0

@Nathan Ernst: Извините, я ошибся. Исправлено – nico

0

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

0

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

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

+2

Это было бы неопределенное поведение, если он удалил указатель 2. На практике я не знать одну платформу, где это приведет к утечке памяти. Скорее всего, вы получите что-то вроде segfault/AV. –

2

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

4

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

0

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

2

Кроме того, рассмотрите возможность использования 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++.

Смежные вопросы