У меня есть C++ код, упомянутый ниже:Беспорядок на практике программирования C++ с обработкой исключений
#include<iostream>
#include<stdexcept>
const long MAX = 10240000;
class Widget{
public:
Widget(){
ok = new int [1024];
prob = new int [100*MAX];
}
~Widget(){
std::cout<<"\nDtoR of Widget is called\n";
delete ok; ok = NULL;
delete prob; prob = NULL;
}
//keeping below public: Intentionally
int* ok;
int* prob;
};
void func(){
Widget* pw = NULL; // <<<<--------------- Issue in Here
try{
pw = new Widget;
}
catch(...){
delete pw;
std::cout<<"\nIn catch BLOCK\n";
if(pw->ok == NULL){
std::cout<<"\n OK is NULL\n";
}
throw;
}
delete pw;
}
int main(){
try{
func();
}
catch(std::bad_alloc&){
std::cout<<"\nError allocating memory."<<std::endl;
}
std::cout<<std::endl;
system("pause");
return 0;
}
Теперь в функции FUNC(), я вижу два различных поведение в зависимости от того, если я не установлен указатель «PW» до NULL, и если я устанавливаю указатель «pw» на NULL (например, код выше). У меня создалось впечатление, что «хорошая» практика - сначала установить указатель на NULL, а затем инициализировать его. Но когда я инициализирую его до NULL, тогда на выходе просто отображается «В catch BLOCK» и более поздних ошибках приложения. но если я не устанавливаю указатель pw на NULL, тогда я вижу деструктор pw и вызывается после выхода, без каких-либо сбоев приложений.
DtoR из Widget называется
В уловов BLOCK
OK является NULL
Ошибка выделения памяти.
Нажмите любую клавишу, чтобы продолжить. , ,
Мой вопрос в том, почему такая разница в одном случае, когда мы не инициализируем указатель «pw» на NULL, а в другом случае мы устанавливаем его в NULL. Почему деструктор вызывается в одном случае и почему он не вызывался в другом.
Примечание: Целью этого кода является выброс bad_alloc exeption.
Не забудьте упомянуть, что он делает, если (pw-> ok) после удаления – PlasmaHH
благодаря vlad для объяснения этого поведения. PlasmaHH: Я согласен. Виноват. Я просто пропустил это. –
Вы также можете добавить, что нет смысла называть 'delete pw;' в блоке 'catch', так как гарантировано, что память не была выделена, если' pw = new Widget; 'throws. –