Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Поведение оператора new в случае ошибки  (Прочитано 8070 раз)
0 Пользователей и 1 Гость смотрят эту тему.
lapulya
Молодой специалист

ru
Offline Offline

« : 22-07-2008 10:58 » 

Алексей1153++,
Цитата
во первых, я предлагаю одним блоком выделить, а не серией. Тут - либо выделилось , либо нет, никакой потери. Если не выделилось = вернёт 0
Ни каких нулей возвращаться не будет в последнем стандарте (а ему уже достаточно много лет.... уже 10 вроде) сказано, что при не возможности выделить запрошенный кусок памяти будет брошено исключение, так что на 0 проверять бесполезно.
Записан

С уважением Lapulya
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 22-07-2008 11:21 » 

lapulya, не нашёл пока в стандарте 2003 года никаких предписаний по поводу обязательности генерации исключения. Нашёл только рассуждения в духе "если аллокатор не объявлен с throw(), то он должен бы генерить исключения, иначе пусть себе возвращает null в случае ошибки".
В мастдайной реализации достаточно поправить 1 на 0 в макро-определении _HAS_EXCEPTIONS, чтобы исключения не генерились.
Записан
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #2 : 22-07-2008 11:59 » new

Вад, сорри я наврал (хотя цитата какой давности стандарта приведена я не знаю). Кстати о стандарте 2003 года мне ничего не известно и я сильно сомневаюсь что он есть... насколько мне известно последняя версия стандарта утвержденная комитетом датируется 1998 годом.

По стандарту, оператор new НИКОГДА не должен возвращать NULL - только бросать исключение - заблуждение. Стандарт гласит RTFM:

5.3.4 New
    . . . .
    13 [Note: unless an allocation function is declared with an empty exception-specification (15.4), throw(), it indicates failure to allocate storage by throwing a bad_alloc exception (clause 15, 18.4.2.1); it returns a non-null pointer otherwise. If the allocation function is declared with an empty exception-specification, throw(), it returns null to indicate failure to allocate storage and a non-null pointer otherwise. ] If the allocation function returns null, initialization shall not be done, the deallocation function shall not be called, and the value of the new-expression shall be null.

Все определяется allocation function. Ни более, ни менее.

Можно писать так

A* a = new (nothrow) A();

тогда исключение бросаться не будет, хотя и это не совсем так. Это касается Standard Language Support Library. Но мы можем в любой момент перекрывать стандартные new'ы. Разумеется, Стандарт изо всех сил рекомедует бросать bad_alloc. Но возвращение NULL все еще официально возможно и без nothrow. Видите ли, у всех восьми операторов, описанных в <new> стоит примечание a C++ program may define a function with this function signature that displaces the default version defined by the C++ Standard library.

Все дело в том, что С++ отдает механизм аллоакции памяти на откуп программитсу (само-собой предоставляя default механизм, описанный в 18.4.1 Storage Allocation and Deallocation). Однако, как только пользователь берет этот механизм в свои руки (что явно и недвусмысленно разрешено Стандартом), то все начинает регулироваться 3.7.3.1 Allocation functions (цитировать не буду, слишком длинно). А там недвусмысленно прописано, что:
- может бросать bad_alloc, а может и возвращать null
- может вызывать new_handler, а может и не вызывать.
Так, что в конечном счете, все зависит от программиста, и Стандарт не запрещает возвращать null из new даже без nothrow.

Виноват исправлюсь )))
Записан

С уважением Lapulya
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 22-07-2008 12:10 » 

Я пользуюсь 2й редакцией ISO/IEC 14882 - она вышла в 2003м. В принципе, кажется, там написано всё то же самое.
Кстати, после выхода этой редакции было очередное (или внеочередное?) "специальное издание" от Страуструпа, которое базировалось на принятой редакции (там это явно автор прописывал, если мне память не изменяет)
« Последнее редактирование: 22-07-2008 12:12 от Вад » Записан
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #4 : 22-07-2008 12:24 » 

Вад,
Гммммм может там в 2003 какието мелкие ошибки исправили... и выпустили обновленную версию... а нет ли там в 2003 версии какого нить предисловия в котором написано что изменилось (хотябы глобально) с версии 1998?

Ну Страуструп комитету не указ Улыбаюсь) Жжешь Жжешь
Записан

С уважением Lapulya
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 22-07-2008 12:32 » 

lapulya, ничего такого не нашёл. Версия однозначно была обновлена, вероятно, было пополнено описание STL. Потому что случилось нам как-то обнаружить во время портирования кода, что реализация STL от Microsoft для VS .NET 2003 местами не соответствовала стандарту, а в 2005й эти несоответствия исчезли.

А Страуструп комитету не указ, это они ему указ - вот он и переработал книгу для соответствия стандарту, насколько я всё это понимаю.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #6 : 22-07-2008 16:36 » 

lapulya, про стандарт  точно не знаю, конечно, но везде вроде в книжках проверялось на 0, ну а я чо, я ничо Улыбаюсь А вот исключений ни разу в new не встречал ещё
Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines