Висячие ссылки. Альтернативы для висящих указателей и ссылок?

Следующий код создает висячие ссылки:

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<> с помощью инструмента статического анализа.
Это будет гарантировать безопасное поведение.

Хорошая практика программирования. Компилятор дает вам более чем достаточно веревки, чтобы повеситься; это ваша ответственность, чтобы убедиться, что нет.

Другими словами, если вы не берете ссылки на массив, а затем удаляете его, у вас не возникнет проблем.

"Но что, если это все равно произойдет?"

Там нет простого ответа, на самом деле. Все дело в обучении и умении использовать инструменты, которые вы пытаетесь использовать.

Другие вопросы по тегам