Reputation: 29
The following code checks for a null reference and creates an object using new
if detected.
The code compiles and the object is created successfully (as anticipated), but the program terminates unexpectedly on the line ref.set_dat(55)
in function main()
(also shown in comments) which is an unexpected behavior.
I don't seem to understand why does the method call to set_dat()
method fail when the object is created successfully using 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;
}
Please note that I have tried substituting ref
, a reference, with obj->
, the original object, but to no avail the same situation is encountered; the program terminates at the same line.
Can anyone please explain me why the program fails to execute at this particular line even after the creation of the object is successful and in the case of an incorrect syntax or logic, suggest me with the correct one? The expected pathway of the program is mentioned in the comments.
Upvotes: 1
Views: 258
Reputation: 598329
X *obj=NULL; X &ref=*obj;
A reference can never be NULL, only a pointer can be NULL. But it is undefined behavior to dereference a NULL pointer. This code is just plain wrong.
Your code re-assigns obj
half-way, so the only way that ref
can update automatically is if ref
refers to the obj
variable itself and not to the X
object that obj
points at:
int main() {
X *obj = NULL;
X* &ref = obj; // <-- a reference to a pointer
if (ref == NULL) { // <-- OK
cout << "NULL REFERENCE DETECTED\n";
obj = new X; // <-- ref can now access the X
} else { // this must not execute
cout << "YOU CANT BE HERE!!!\n";
}
ref->set_dat(55); // <-- OK
cout << "Data 1 has value " << ref->get_dat() << endl;
delete obj;
cout << "Delete successful\n";
obj = NULL; // <-- ref no longer accesses an X
if (ref == NULL) { // <-- OK
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;
}
Alternatively, change ref
into a pointer instead of a reference:
int main() {
X *obj = NULL;
X** ref = &obj; // <-- a pointer to a pointer
if (*ref == NULL) { // <-- OK
cout << "NULL REFERENCE DETECTED\n";
obj = new X; // <-- *ref can now access the X
} else { // this must not execute
cout << "YOU CANT BE HERE!!!\n";
}
(*ref)->set_dat(55); // <-- OK
cout << "Data 1 has value " << (*ref)->get_dat() << endl;
delete obj;
cout << "Delete successful\n";
obj = NULL; // <-- *ref no longer accesses an X
if (*ref == NULL) { // <-- OK
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;
}
Upvotes: 7