Висячие ссылки. Альтернативы для висящих указателей и ссылок?
Следующий код создает висячие ссылки:
int main()
{
int *myArray = new int[2]{ 100, 200 };
int &ref = myArray[0];
delete[] myArray;
cout << ref; // Use of dangling reference.
}
Я знаю, что не следует удалять массив, но в большой программе, что если кто-то удалит память, на которую у меня есть ссылка? Можно ли как-то быть уверенным, что никто не удалит массив?
Какова лучшая стратегия против висячих ссылок и висячих указателей?
5 ответов
Не удаляйте память до того, как закончите с ней.
Звучит глупо, но это ваша единственная защита - правильно понять, кому принадлежит память за каждой переменной и когда ее можно безопасно освободить.
Умные указатели могут помочь, но вышеупомянутое все еще применяется.
Возможно, некоторые инструменты статического анализа могут идентифицировать тривиальный случай, который у вас здесь есть, но даже тогда это должно быть второй линией защиты, с вашей первой дисциплиной в управлении памятью.
Держите их в нужной области:
int main(){
int *myArray;
myArray = new int[2]{ 100, 200 };
{
int& ref = myArray[0];
// use the ref here
cout<<ref; \\no longer a dangling reference
} // ref falls out of scope here
delete[] myArray;
}
Пациент: Доктор, мне больно, когда я делаю это...
Доктор: Тогда прекрати это делать...
Не освобождайте память, имея на нее ссылку.
РЕДАКТИРОВАТЬ
Единственный способ поймать это - отладить, провести хорошие модульные тесты и запустить под valgrind, или запустить вашу программу под valgrind.
Все ответы здесь были "будьте осторожны!" И "используйте хорошие методы программирования!".
Это не очень удовлетворительный ответ. Эти проблемы существуют в C более 40 лет, и они все еще распространены в любом проекте C++ значительного размера.
Самые важные рекомендации, которые вы услышите, люди рекомендуют:
- Используйте умные указатели
- Используйте RAII
И то, и другое верно, но вы можете сделать больше.
В 2015 году Фонд Standard C++ выпустил Библиотеку поддержки рекомендаций.
Вы можете писать программы на C++, которые статически безопасны и не имеют утечек ресурсов. Вы можете сделать это без потери производительности и без ограничения выразительной силы C++. Эта модель для безопасного для типов и ресурсов C++ была реализована с использованием комбинации стандартных средств языка C++ стандарта ISO, статического анализа и небольшой библиотеки поддержки (написанной на стандарте ISO C++).
Я рекомендую вам использовать GSL Owner<>
с помощью инструмента статического анализа.
Это будет гарантировать безопасное поведение.
Хорошая практика программирования. Компилятор дает вам более чем достаточно веревки, чтобы повеситься; это ваша ответственность, чтобы убедиться, что нет.
Другими словами, если вы не берете ссылки на массив, а затем удаляете его, у вас не возникнет проблем.
"Но что, если это все равно произойдет?"
Там нет простого ответа, на самом деле. Все дело в обучении и умении использовать инструменты, которые вы пытаетесь использовать.