Вы можете удалить p1
или p2
. Не будет никакой разницы. Но вы не должны удалить оба. Плюс после того, как вы удалили один, вы не должны использовать другой. За это отвечает программист. Сам язык не даст никакой помощи. Существует множество различных способов написания кода.
Существует несколько методов/шаблонов для обработки этого. Очень часто для этого используются интеллектуальные указатели. Посмотрите на документацию std::shared_ptr. Не используйте устаревшие auto_ptr
.
Мой любимый паттерн - «собственность». Это означает, что один указатель «владеет» распределением, а все остальные просто используют. Это требует определенной дисциплины во время программирования, но как только это усилие применяется, полученный код ясен и прост. Например:
class MyClass
{
public: ~MyClass() { for(char *p: myStringsDict) delete p; }
private:
std::unordered_set<char*> myStringsDict;
};
Глядя на этот класс ясно (хотя было бы неплохо добавить правильный комментарий), что он владеет словарем строк, и эти строки действительны до тех пор, пока существует экземпляр этого класса , Эти указатели могут использоваться в структурах, принадлежащих этому классу, их можно передавать как параметры для функций и т. Д. Ясно, что их больше не следует использовать.
При программировании сервера при работе нескольких потоков двойное удаление может быть очень опасным и трудноотслеживаемым. Поскольку после удаления первого указателя память становится свободной и может быть выделена для какой-либо другой цели в другом потоке. Когда второй указатель освобождается, может случиться, что он удаляет допустимое выделение, в то время как другой фрагмент кода не знает об этом и продолжает использовать эту часть памяти.
Действительно хорошее решение для всех этих проблем - сбор мусора. Когда используются явные распределения, программисту необходимо применить дополнительные усилия тем или иным способом.
*** И что произойдет с p1? *** Неопределенное поведение, если вы попытаетесь разыменовать p1. – drescherjm