why no seg fault due to shallow copy?

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
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <iostream>

using namespace std;

template <class x>
class Array{
public:
        Array(int len);
        ~Array();
        Array(const Array& c);
        void print_values();
        void set_values(int in);
        Array& operator=(const Array& in);
//private:
        int _len;
        x* data;
};

template <class x>
Array<x>::Array(int len)
{
        cout << "inside constructor" << endl;
        _len = len;
        data = new x[_len];
}

template <class x>
Array<x>::~Array()
{
        cout << "inside destructor" << endl;
        delete[] data;
}


template <class x>
Array<x>::Array(const Array<x>& in)
{
        _len = in._len;
        data = in.data;
        cout << "address of data = " << data << endl;
        cout << "address of data = " << in.data << endl;
}

template <class x>
Array<x>& Array<x>::operator=(const Array<x>& in)
{
}       

template <class x>
void Array<x>::print_values()
{
        x* temp = data;
        for(int i= 0; i < _len; i++)
        {
                cout << "value = " << *temp << endl;
                *temp = i;
                temp++;
        }
}

template <class x>
void Array<x>::set_values(int in)
{
        x* temp = data;
        for(int i = 0; i < _len; i++)
        {
                *temp = i+ in;
                temp++;
        }
}
int main(int argc, char** argv)
{

        Array<int>* local_obj_p = new Array<int>(5);
        cout << "address of data = " << &local_obj_p->data << endl;
        Array<int> one_more_obj(*local_obj_p);
        one_more_obj.set_values(100);
        local_obj_p->print_values();
        delete local_obj_p;
        one_more_obj.set_values(200);
        cout << "address of data = " << one_more_obj.data << endl;
        one_more_obj.print_values();
        return 0;
}

Here's the output of the program
inside constructor
address of data = 0x603018
address of data = 0x603030
address of data = 0x603030
value = 100
value = 101
value = 102
value = 103
value = 104
inside destructor
address of data = 0x603030
value = 200
value = 201
value = 202
value = 203
value = 204
inside destructor

why the copy constructor works fine in this code? even though copy constructor would do a shallow copy of data and delete should de-allocate the memory and if the same memory is accessed it should result in SEG_FAULT. But the print statements in copy constructor shows it is pointing at different memory locations.
if the same memory is accessed it should result in SEG_FAULT.


No. It results in undefined behavior, which might segfault, or it might not. This is what makes accessing bad memory so troublesome... it sometimes slips by unnoticed and your program works "fine" until a month later when you change something completely unrelated and then all of the sudden nothing works any more.

But the print statements in copy constructor shows it is pointing at different memory locations.


Nope, they're both pointing to the same memory. The problem is you're printing the wrong pointer in main.

1
2
3
address of data = 0x603018  <- &local_obj_p->data
address of data = 0x603030  <-  one_more_obj->data
address of data = 0x603030  <-  local_obj_p->data


Notice how the first one is printing the address of the pointer (ie: a pointer to a pointer) and not the actual pointer.
Hi Disch,

Thanks for the response.
About the address display, yes its my bad.
though i carried following experiment -
1. I created three objects as shown in here -
1
2
3
4
5
6
7
8
9
10
11
12
13
int main(int argc, char** argv)
{

        Array<int>* local_obj_p = new Array<int>(5);
        cout << "address of data = " << &local_obj_p->data << endl;
        Array<int> one_more_obj(*local_obj_p);
        one_more_obj.set_values(100);
        one_more_obj.print_values();
        Array<int> new_obj(*local_obj_p);
        delete local_obj_p;
        cout << "after delete operation" << endl;
        return 0;
}

address of the data =0x7fff939de968
inside copy constructor
address of data = 0x603030
address of data = 0x7fff939de958
inside destructor
after delete operation
inside destructor
inside destructor
*** glibc detected *** ./a.out: double free or corruption (fasttop): 0x0000000000603030 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x733b6)[0x7f5e1dbb23b6]
/lib64/libc.so.6(cfree+0x6c)[0x7f5e1dbb72dc]
./a.out[0x400e05]
./a.out[0x400c1b]
/lib64/libc.so.6(__libc_start_main+0xfd)[0x7f5e1db5dbfd]
./a.out[0x400a69]
======= Memory map: ========

this resulted in seg_fault. why there is seg fault during third destructor? why not during second destructor call?

i am suspecting is this due to delete not freeing memory back to OS, where as when program cleanup is done, it frees memory back and result in seg_fault during second freeing operation?
You're trying to define behavior that's undefined. Trying to rely on behavior that is unreliable. This is an exercise in futility.

thanks for proper response. i will stop doing this exercise...:)
Topic archived. No new replies allowed.