I wanted to ask that when I don't write any copy constructor explicitly so the compiler automatically generates the copy constructor which performs shallow copy by default right? So in the main() program when I changed the values of integers a, b and pointer p only the value of p changed and values of a and b remain unchanged in the copied object. Why the values of a & b didn't change too? My code is:
#include <iostream>
#include <string.h>
using namespace std;
class Dummy {
private:
int a, b;
int *p;
public:
Dummy() {
p = new int;
}
void setData(int x, int y, int z) {
a = x;
b = y;
*p = z;
}
void showData() {
cout << "a = " << a << " b = " << b;
cout << " p = " << *p << endl;
}
~Dummy() {
delete p;
}
};
int main() {
Dummy d1;
d1.setData(3, 4, 5);
Dummy d2 = d1;
d1.showData();
d2.showData();
d1.setData(6, 7, 8);
d1.showData();
d2.showData();
return 0;
}
The output of my program is:
a = 3 b = 4 p = 5
a = 3 b = 4 p = 5
a = 6 b = 7 p = 8
a = 3 b = 4 p = 8
What I'm saying is while the pointer of object d2 changed when I changed the values of object d1 then why didn't the values of a & b of object d2 changed too?
Also I'm using delete keyword in the destructor to delete the dynamically allocated pointer:
~Dummy() {
delete p;
}
But it's crashing my program instead. Why is that?
You've totally got it wrong - The idea of shallow copy
. Actually, c++
does not have anything called deep copy
built into itself. So, calling something shallow copy
is a bit wrong
. And just the use of these words shallow copy
creates a lot of confusion
too.
Now, let me explain, what happens when cpp
performs initialization using assignment
. cpp
or c
(while copying struct) has a concept called bitwise copy
. In this concept, all the member variables of one object(struct object/class object - you can say either) is identically copied to another object
. Now, it's totally wrong idea
that, both objects point to same memory location
. In actual, both object
has their own memory location
and of course, their variables
occupy different memory spaces
. For you, I have write some tests regarding memory. You would understand perfectly, if you just see the test and it's output:
#include <iostream>
#include <string.h>
using namespace std;
class Dummy {
int a, b;
int *p;
public:
Dummy() {
p = new int;
}
void setData(int x, int y, int z) {
a = x;
b = y;
*p = z;
}
void showData() {
cout << "a = " << a << " b = " << b;
cout << " p = " << *p << endl;
cout << endl; // an extra new line for readability of output
}
void showMemory() {
cout << "addr(a) = " << &a << " addr(b) = " << &b;
cout << " addr(p) = " << &p << endl;
}
~Dummy() {
*p = 100;
delete p;
}
};
// testing memory
void memoryTest() {
cout << "testing d1:" << endl;
Dummy d1;
d1.setData(3, 4, 5);
cout << "addr(d1) = " << &d1 << endl;
d1.showMemory();
cout << endl ;
cout << "testing d2:" << endl;
Dummy d2 = d1;
cout << "addr(d2) = " << &d2 << endl;
d2.showMemory();
}
int main() {
// memoryTest
memoryTest();
return 0;
}
And the output of the test was:
testing d1:
addr(d1) = 0x6dfed4
addr(a) = 0x6dfed4 addr(b) = 0x6dfed8 addr(p) = 0x6dfedc
testing d2:
addr(d2) = 0x6dfec8
addr(a) = 0x6dfec8 addr(b) = 0x6dfecc addr(p) = 0x6dfed0
This clearly shows that, the memory occupied by those two objects d1
and d2
are totally different.
*p=8
, it affects both d1
and d2
?:When you assign, Dummy d2 = d1;
, we may say something happended like below(though, it's not actually happen when bitwise copy is applied, it's just for clarity):
d2.p = d1.p
So, we know that, d1.p
and d2.p
contains the same memory location(note: d1.p is a pointer. so, it does not contain any integer, rather it contains memory address of an int).
So, when you write *p = 8
, you are telling the program to go to the memory location targeted by p and change the value of that memory location to 8.(note, here, you didn't change the content of d1.p
, d1.p
still contains the same memory location. rather, you just changed that memory location's content from 5 to 8). That's why when you call d2.p
, you get the changed value. cause, d2.p
contains the same memory location as d1.p
.
p
in destructor?:Now, let me first ask you, can you free a memory what is already freed. You can write the code, but the behavior is undefined. It may crashes your program or it may do nothing.
Well, in Dummy
destructor
you've written delete p;
. Now, either d2
or d1
would be destroyed first. Let's assume, d2
is destroyed first
. So, when d2's
destroyer is called, p
is freed
. Then, d1's
destroyer will be called and it'll also try to free p
. But p
is already freed. And in your case, the program meets a crash for this reason.
Hope, everything is clear to you now.
If anything is not clear about what I've described above, then ask questions, I will try my best to answer them too.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments