Вопрос:
Что происходит, когда два указателя указывают на один и тот же адрес? Это вызовет проблему безопасности?
Ответ №1
Сам факт одобрен, но вы столкнетесь с поведением undefined, если вы вызываете delete на одном из указателей и пытаетесь использовать другое потом:
int* x = new int(5); int* y = x; delete x; //y is a dangling pointer
Если вы столкнетесь с ситуацией, когда вам нужно использовать несколько указателей на один и тот же адрес памяти, вы должны изучить интеллектуальные указатели.
Ответ №2
Безопасно иметь более одного указателя на один и тот же адрес, но убедитесь, что вы знаете, что если память удаляется с помощью delete или если исходная переменная выходит за пределы области видимости, то доступ к ней будет undefined.
Ответ №3
Зависит:
Для классических указателей. У вас может быть несколько указателей, указывающих на одну и ту же ячейку памяти, но управление местоположением будет просачиваться по всем указателям. Удаление/освобождение памяти одного указателя приведет к поведению undefined при использовании других указателей. Обратите внимание, что лучше всего сделать указатель NULL после освобождения хранилища для предотвращения двойного удаления и при использовании нескольких указателей это не прагматически правдоподобно.
Умные указатели
Auto_Pointers (С++ 98): реализация класса шаблонов С++ предоставила механизм, позволяющий одному и только одному указателю указывать на одно местоположение памяти. Как правило, поскольку эти указатели реализованы в стеке как объект, когда они выходят из области действия, адрес будет автоматически освобожден. Но копирование одного указателя на другое сделает другой непригодным.
Shared_Pointers (С++ 2003 TR1): ускорить библиотеку, предоставляемую совместно используемыми указателями, которая имеет счетчик ссылок, который определяет, когда объект может быть освобожден. Это лучше, чем auto_ptrs, так как вы можете использовать несколько удобных указателей, разделяющих одну и ту же ячейку памяти.
Unique_Pointers (С++ 11). Подобно Auto_pointers, но наследует концепцию передачи права собственности, когда не созданы объекты присваивания и копирования. Вместо этого применяется метод перемещения, чтобы сделать его более понятным, каково намерение.
Ответ №4
Если оба указателя имеют один и тот же тип, нет проблемы:
int a = 42; int *p = &a int *q = p; *p = 3145; // no problem, a and *q are now also equal 3145
Если оба указателя имеют разные типы (за исключением char *) и указывают на один и тот же объект, разыменование одного из указателей имеет поведение undefined.
float a = 42.0f; float *p = &a; int *q = (int *) p; // we assume pointer is correctly aligned *q = 0; // undefined behavior, it breaks aliasing rules
Эти правила известны как правила сглаживания C-указателей. Вы можете найти список правил сглаживания C в n1570.pdf в пункте 6.5p7.
Ответ №5
Оба объекта указывают на один и тот же адрес кучи.
В то время, когда вы отмените выделение памяти, это может вызвать проблемы с другими объектами, указывающими на тот же адрес.