Следующий код проверяет пустую ссылку и создает объект с использованием new
, если обнаружено.Null reference check in C++
Код компилируется, и объект создается успешно (как ожидалось), но программа неожиданно завершается в строке ref.set_dat(55)
в функции main()
(также показана в комментариях), что является неожиданным поведением.
Не похоже, почему метод вызывает метод set_dat()
сбой при успешном создании объекта с использованием new
?
class X {
private:
int *_dat,*__dat;
public:
X(); // constructor
~X(); // destructor
int get_dat() const {
return *(this->_dat);
}
int get__dat() const {
return *(this->__dat);
}
void set_dat(int data) {
*(this->_dat)=data;
}
void set__dat(int data) {
*(this->__dat)=data;
}
};
X::X() {
this->_dat=new int(0); // assign default value of 0
this->__dat=new int(0);
cout << "Construction Successful\n";
}
X::~X() {
delete this->_dat;
delete this->__dat;
_dat=NULL;
__dat=NULL;
cout << "Destruction Successful\n";
}
int main() {
X *obj=NULL;
X &ref=*obj;
if (&ref==NULL) {
cout << "NULL REFERENCE DETECTED\n";
obj=new X;
} else { // this must not execute
cout << "YOU CANT BE HERE!!!\n";
}
ref.set_dat(55); // Program terminates at this statement
cout << "Data 1 has value " << ref.get_dat() << endl;
delete obj;
cout << "Delete successful\n";
obj=NULL;
if (&ref==NULL) {
cout << "NULL REFERENCE\nPROGRAM NOW TERMINATES";
} else { // this block must not execute
ref.set_dat(58);
ref.set__dat(99);
cout << "Data 1 now is " << ref.get_dat() << endl;
cout << "Data 2 now is " << ref.get__dat() << endl;
delete obj;
}
return 0;
}
Пожалуйста, обратите внимание, что я попытался подставляя ref
, ссылку, с obj->
, исходный объект, но безрезультатно такая же ситуация встречается; программа завершается в одной строке.
Может ли кто-нибудь объяснить мне, почему программа не может выполнить на этой конкретной линии даже после того, как создание объекта прошло успешно, а в случае неправильного синтаксиса или логики - предложите мне правильный? Ожидаемый путь программы упоминается в комментариях.
'X * obj = NULL; X & ref = * obj; 'Это неопределенное поведение, полная остановка. Даже без ошибок компилятора, это неправильно, и может привести к чему угодно. Думать, что это должно делать, не имеет смысла. – deviantfan
@deviantfan Я не понимаю, как это неопределенное поведение? Это вполне логично. Пожалуйста, уточните подробнее. – zeus
Возможно, это логично для вас, но стандарты C++ не позволяют этого (периода). Если в стандарте что-то классифицируется как «неопределенное поведение», это означает, что почти все может произойти. Он может работать, он может дать ошибку компилятора, он может упасть, он может сжечь ваш компьютер ... вы понимаете, что я имею в виду, он может делать «что угодно». И это может изменить поведение с течением времени, etc.etc.etc. – deviantfan