Действительно ли новый возврат аннулирует в любом случае?

Я получал ту же ошибку от JDBC. Проверено все, и мой запрос был в порядке. Оказалось, в where where у меня есть аргумент:

where s.some_column = ?

И значение аргумента, в котором я проходил, было null. Это также дает ту же ошибку, которая вводит в заблуждение, потому что при поиске в Интернете вы оказываетесь в том, что что-то не так с структурой запроса, но это не в моем случае. Просто подумал, что кто-то может столкнуться с тем же вопросом

52
задан EvilTeach 8 March 2009 в 00:55
поделиться

3 ответа

VC6 был несовместим по умолчанию в этом отношении. VC6 new возвратился 0 (или NULL).

Вот Статья КБ Microsoft об этой проблеме наряду с их предложенным обходным решением с помощью пользовательского new обработчик:

, Если у Вас есть старый код, который был написан для поведения VC6, можно получить то же самое поведение с более новыми компиляторами MSVC (что-то как 7,0 и позже) путем соединения в объектном файле, названном nothrownew.obj. Существует на самом деле справедливо сложный подшипник в 7,0 и 7,1 компиляторах (VS2002 и VS2003), чтобы определить, приняли ли они значение по умолчанию к неброску или броску new.

кажется, что мс убрала это в 8,0 (VS2005) — теперь это всегда принимает значение по умолчанию к броску, новому, если Вы конкретно не связываетесь с nothrownew.obj.

Примечание, что можно указать, что Вы хотите new возвратиться 0 вместо того, чтобы бросить std::bad_alloc использование std::nothrow параметр:

SomeType *p = new(std::nothrow) SomeType;

Это, кажется, работает в VC6, таким образом, это мог быть путь к более или менее, механически исправляют код для работы того же со всеми компиляторами, таким образом, Вы не должны переделывать существующую обработку ошибок.

56
ответ дан Wolf 7 November 2019 в 19:26
поделиться

Я хотел бы добавить (несколько спорное) мнение, что проверка ПУСТОЙ УКАЗАТЕЛЬ после попытки выделения является в значительной степени упражнением в тщетности. Если Ваша программа когда-нибудь сталкивается с той ситуацией, возможности - Вы, не может сделать намного больше, чем выход быстро. Вероятно, что любая последующая попытка выделения также перестанет работать.

, не проверяя на ПУСТОЙ УКАЗАТЕЛЬ, Ваш последующий код попытался бы разыменовать Нулевого указателя, который имеет тенденцию выходить из программы быстро с относительно уникальным (и легко debuggable) условие выхода.

я не пытаюсь говорить Вы из проверки ПУСТОЙ УКАЗАТЕЛЬ, это - конечно, добросовестное программирование. Но Вы не получаете много от него, если в очень конкретных случаях, где можно, возможно, хранить некоторую информацию восстановления (не выделяя больше памяти), или свободную менее важную память, и т.д. Но те случаи, не будет относительно редко для большинства людей.

, Учитывая это, я просто доверил бы компилятор для броска bad_alloc, лично - по крайней мере в большинстве случаев.

19
ответ дан 7 November 2019 в 19:26
поделиться

На основе спецификации C++ это будет всегда бросать станд.:: bad_alloc, когда Вы используете просто новый без параметрических усилителей, но конечно могут быть некоторые не совместимые компиляторы.

я не кодировал бы, чтобы быть совместимым с не C++ совместимые компиляторы все же. Причем VC6 является одним из них в этом отношении.

Это - хорошая практика, хотя всегда устанавливать Ваш указатель в NULL после удаления их. Так из-за этого проверка ПУСТОЙ УКАЗАТЕЛЬ все еще необходима.

Однако вот пара опций к чистке Вашего кода:

Опция 1: Установка Вашего собственного нового обработчика

А безопасный способ очистить Ваш код должна была бы звонить: set_new_handler сначала.

Затем Вы могли проверить на ПУСТОЙ УКАЗАТЕЛЬ в своем обработчике и бросить станд.:: bad_alloc там, если ПУСТОЙ УКАЗАТЕЛЬ возвращается.

, Если Вам нравятся исключения лучше, затем это - Ваш лучший выбор. Если Вам нравится возвращать ПУСТОЙ УКАЗАТЕЛЬ лучше затем, можно также сделать это путем выполнения выгоды в новом обработчике.

Опция 2: Используя перегруженный, новый

, заголовочный файл стандарта C++ определяет структуру nothrow, который пуст. Можно использовать объект этой структуры, внутри новой для получения ее перегруженной версии, которая всегда возвращает ПУСТОЙ УКАЗАТЕЛЬ.

void* operator new (size_t size, const std::nothrow_t &);
void* operator new[] (void *v, const std::nothrow_t &nt);

Так в Вашем коде:

 char *p = new(std::nothrow) char[1024];

Вот хорошая ссылка для дополнительных материалов для чтения

9
ответ дан Brian R. Bondy 7 November 2019 в 19:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: