99. Не используйте недействительные объекты и небезопасные функции

99. Не используйте недействительные объекты и небезопасные функции

Резюме

Вы же не используете просроченные лекарства? И недействительные объекты, и "антикварные", но небезопасные функции способны навредить здоровью ваших программ.

Обсуждение

Имеется три основные категории недействительных объектов.

• Уничтоженные объекты. Типичными примерами таких объектов являются автоматические объекты, вышедшие из области видимости, и удаленные динамические объекты. После того как вы вызвали деструктор объекта, его время жизни истекло, и любые действия с ним небезопасны и приводят к непредсказуемым последствиям.

• Семантически недействительные объекты. Типичные примеры включают "висячие" указатели на удаленные объекты (например, указатель p после выполнения delete p;) и недействительные итераторы (например, vector<T>::iterator i после вставки в начало контейнера, к которому обращается итератор). Заметим, что висячие указатели и недействительные итераторы концептуально идентичны, и последние часто непосредственно содержат первые. Обычно небезопасно и непредсказуемо делать что-либо с такими указателями и итераторами, за исключением присваивания другого корректного значения недействительному объекту (например, p = new Object; или i = v.begin();).

• Объекты, которые никогда не были действительными. Примеры включают объекты, "полученные" путем преобразования указателя с использованием reinterpret_cast (см. рекомендацию 92) или при обращении за пределы границ массива.

Никогда не забывайте о времени жизни объекта и его корректности. Не разыменовывайте недействительные итераторы и указатели. Не делайте никаких предположений о том, что делает и чего не делает оператор delete; освобожденная память — это освобожденная память, и обращений к ней не должно быть ни при каких условиях. Не пытайтесь играться со временем жизни объекта путем вызова деструктора вручную (например, obj.~T()) с последующим вызовом размещающего new (см. рекомендацию 55).

Не используйте небезопасное наследство С: strcpy, strncpy, sprintf или прочие функции, которые выполняют запись в буфер без проверки выхода за его пределы. Функция strcpy не выполняет проверки границ буфера, а функция [C99] strncpy выполняет проверку, но не добавляет нулевой символ при выходе на границу. Обе эти функции — потенциальный источник неприятностей. Используйте современные, более безопасные и гибкие структуры и функции, такие, которые имеются в стандартной библиотеке С++ (см. рекомендацию 77). Они не всегда совершенно безопасны (в основном это связано с вопросами эффективности), но существенно меньше подвержены ошибкам и позволяют создавать гораздо более безопасный код.

Ссылки

[C99] • [Sutter00] §1 • [Sutter04] §2-3

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Объекты DataSet с множеством таблиц и объекты DataRelation

Из книги Язык программирования С# 2005 и платформа .NET 2.0. [3-е издание] автора Троелсен Эндрю

Объекты DataSet с множеством таблиц и объекты DataRelation До этого момента во всех примерах данной главы объекты DataSet содержали по одному объекту DataTable. Однако вся мощь несвязного уровня ADO.NET проявляется тогда, когда DataSet содержит множество объектов DataTable. В этом случае вы можете


19.2.3.2. Используйте автоинструменты GNU

Из книги Искусство программирования для Unix автора Реймонд Эрик Стивен

19.2.3.2. Используйте автоинструменты GNU Определение конфигурационных параметров должно быть выполнено во время компиляции. Значительное преимущество дистрибутивов с открытым исходным кодом заключается в том, что они позволяют адаптировать пакет к обнаруженной среде на


Совет 5. Используйте интервальные функции вместо одноэлементных

Из книги Эффективное использование STL автора Мейерс Скотт

Совет 5. Используйте интервальные функции вместо одноэлементных Есть два вектора, v1 и v2. Как проще всего заполнить v1 содержимым второй половины v2? Только не надо мучительно размышлять над тем, что считать «половиной» при нечетном количестве элементов в v2. Просто


Совет 44. Используйте функции контейнеров вместо одноименных алгоритмов

Из книги Основы AS/400 автора Солтис Фрэнк

Совет 44. Используйте функции контейнеров вместо одноименных алгоритмов Некоторые контейнеры содержат функции, имена которых совпадают с именами алгоритмов STL. Так, в ассоциативных контейнерах существуют функции count, find, lower_bound, upper_bound и equal_range, а в контейнере list


Объекты OS/400 и системные объекты MI

Из книги Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ автора Мейерс Скотт

Объекты OS/400 и системные объекты MI Несколько типов объектов имеются и в OS/400, и в MI. Типы объектов OS/400 перечислены в таблице 5.1. Для сравнения, в таблице 5.2 приведены системные объекты MI. Помните, что в каждой новой версии AS/400 добавляются новые функции и даже новые объекты.


Правило 13: Используйте объекты для управления ресурсами

Из книги Искусство программирования для Unix автора Реймонд Эрик Стивен

Правило 13: Используйте объекты для управления ресурсами Предположим, что мы работаем с библиотекой, моделирующей инвестиции (то есть акции, облигации и т. п.), и классы, представляющие разные виды инвестиций, наследуются от корневого класса Investment:class Investment {...} // корневой


19.2.3.2. Используйте автоинструменты GNU

Из книги Стандарты программирования на С++. 101 правило и рекомендация автора Александреску Андрей

19.2.3.2. Используйте автоинструменты GNU Определение конфигурационных параметров должно быть выполнено во время компиляции. Значительное преимущество дистрибутивов с открытым исходным кодом заключается в том, что они позволяют адаптировать пакет к обнаруженной среде на


88. В качестве аргументов алгоритмов и компараторов лучше использовать функциональные объекты, а не функции

Из книги VBA для чайников автора Каммингс Стив

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


Используйте отступы!

Из книги C++ для начинающих автора Липпман Стенли

Используйте отступы! Правильное использование отступов служит основой создания понятного программного кода. В примере из предыдущего раздела каждая пара операторов, определяющих одну структуру, напечатана с одним и тем же отступом. При наличии отступов проще выяснить,


8.2. Глобальные объекты и функции

Из книги автора

8.2. Глобальные объекты и функции Объявление функции в глобальной области видимости вводит глобальную функцию, а объявление переменной – глобальный объект. Глобальный объект существует на протяжении всего времени выполнения программы. Время жизни глобального


12.3. Объекты-функции

Из книги автора

12.3. Объекты-функции Наша функция min() дает хороший пример как возможностей, так и ограничений механизма шаблонов:template typename Typeconst Type&min( const Type *p, int size ){Type minval = p[ 0 ];for ( int ix = 1; ix size; ++ix )if ( p[ ix ] minval )minval = p[ ix ];return minval;}Достоинство этого механизма – возможность определить


12.3.1. Предопределенные объекты-функции

Из книги автора

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


12.3.2. Арифметические объекты-функции

Из книги автора

12.3.2. Арифметические объекты-функции Предопределенные арифметические объекты-функции поддерживают операции сложения, вычитания, умножения, деления, взятия остатка и вычисления противоположного по знаку значения. Вызываемый оператор – это экземпляр, ассоциированный с


12.3.3. Сравнительные объекты-функции

Из книги автора

12.3.3. Сравнительные объекты-функции Сравнительные объекты-функции поддерживают операции равенства, неравенства, больше, больше или равно, меньше, меньше или равно.equal_tostring stringEqual;sres = stringEqual( sval1, sval2 );ires = count_if( svec.begin(), svec.end(),Равенство:equal_toType* equal_tostring(), sval1 );not_equal_tocomplex


12.3.4. Логические объекты-функции

Из книги автора

12.3.4. Логические объекты-функции Логические объекты-функции поддерживают операции "логическое И" (возвращает true, если оба операнда равны true, – применяет оператор &&, аcсоциированный с типом Type), "логическое ИЛИ" (возвращает true, если хотя бы один из операндов равен true, –


19.2.4. Объекты-исключения и виртуальные функции

Из книги автора

19.2.4. Объекты-исключения и виртуальные функции Если сгенерированный объект-исключение имеет тип производного класса, а обрабатывается catch-обработчиком для базового, то этот обработчик не может использовать особенности производного класса. Например, к функции-члену value(),