Hi!
This is a question about "reserving memory" (new...) and then freeing it with delete.
Usually if I delete some memory more than once... a runtime error crash occurs.
But I have an example below, where no runtime error occurs. Even though the memory is deleted 3 times!! (I'm using gcc's g++)
The example uses smart-pointers.
My question:
*Am I correct that the code below has errors?
*Am I correct that g++ does not detect these errors? What do other compilers do?
*Could this be a compiler bug? Should I contact the gcc team?
The int-memory-object (pointed-to by ip) is deleted 3 times: see lines 59, 62, 67
The deleted int-memory-object, can still be accessed: see lines 61, 64, 68
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
//
// Below an int-object is created with new int(1)
// Usually a runtime error occurs if an object is deleted 2 or more times.
// But in the course of the execution, the object is deleted 3 times --> Why does no runtime error occur?
#include <iostream>
using std::cout;
using std::endl;
class U_a
{
friend class B;
U_a(int *p) : ip(p), use(1) {}
~U_a() {
std::cout << "Delete " << ip << std::endl;
delete ip;
}
int *ip;
size_t use; // use-counter, used by smart-pointer...
};
class B // uses smart pointers
{
public:
B(int *p) : ptr(new U_a(p)) {}
B(const B &rhs) : ptr(rhs.ptr) { // not used
++ptr->use;
}
B &operator=(const B &rhs) { // not used
++rhs.ptr->use;
if (--ptr->use == 0)
delete ptr;
ptr = rhs.ptr;
return *this;
}
int get_ip_val() {
return *ptr->ip;
}
~B() {
if (--ptr->use == 0)
delete ptr;
}
private:
U_a *ptr;
};
int main()
{
int *ip = new int(1); // created "object-pointed-to-by ip" and give it initial value 1
{
B b1(ip);
{
B b2(ip); // deliberate bad use of smart-pointer class. This is not the copy constructor! ;)
cout << "Val: " << b1.get_ip_val() << endl;
} // b2's destructor has run and deleted "object-pointed-to-by ip"!
cout << "Val: " << b1.get_ip_val() << endl; // 1)*** Why can we still get "object-pointed-to-by ip"? Why is there no runtime error?
} // 2)*** b1's destructor has run and deleted "object-pointed-to-by ip" the second time!!! Why is there still no runtime error?
*ip = 4; // 3)*** Why is there still no runtime error?
std::cout << "Delete " << ip << std::endl;
delete ip; // here we delete "object-pointed-to-by ip" a 3rd time 4)*** Why is there still no runtime error?
*ip = 5; // 5)*** Why is there still no runtime error?
return 0;
}
|