Consider the following c++ code:
class test
{
public:
int val;
test():val(0){}
~test()
{
cout << "Destructor called\n";
}
};
int main()
{
test obj;
test *ptr = &obj;
delete ptr;
cout << obj.val << endl;
return 0;
}
I know delete should be called only on dynamically allocated objects but what would happen to obj now ?
Ok I get that we are not supposed to do such a thing, now if i am writing the following implementation of a smart pointer, how can i make sure that such a thing does’t happen.
class smart_ptr
{
public:
int *ref;
int *cnt;
smart_ptr(int *ptr)
{
ref = ptr;
cnt = new int(1);
}
smart_ptr& operator=(smart_ptr &smptr)
{
if(this != &smptr)
{
// House keeping
(*cnt)--;
if(*cnt == 0)
{
delete ref;
delete cnt;
ref = 0;
cnt = 0;
}
// Now update
ref = smptr.ref;
cnt = smptr.cnt;
(*cnt)++;
}
return *this;
}
~smart_ptr()
{
(*cnt)--;
if(*cnt == 0)
{
delete ref;
delete cnt;
ref = 0;
cnt = 0;
}
}
};
You’ve asked two distinct questions in your post. I’ll answer them separately.
The behavior of your program is undefined. The C++ standard makes no comment on what happens to
objnow. In fact, the standard makes no comment what your program does before the error, either. It simply is not defined.Perhaps your compiler vendor makes a commitment to what happens, perhaps you can examine the assembly and predict what will happen, but C++, per se, does not define what happens.
Practially speaking1, you will likely get a warning message from your standard library, or you will get a seg fault, or both.
1: Assuming that you are running in either Windows or a UNIX-like system with an MMU. Other rules apply to other compilers and OSes.
Never initialize
smart_ptrwith the address of a stack variable. One way to do that is to document the interface tosmart_ptr. Another way is to redefine the interface so that the user never passes a pointer tosmart_ptr; makesmart_ptrresponsible for invokingnew.