Lab 5 - Copy Constructors and Assignment Operators

The purpose of this lab is to see why copy constructors and assignment operators are vital for class which have dynamic array member variables.

Copy the class list.cpp to your directory using wget or cut/paste (see Labs 1 and 2 for these commands). This is a class which has a dynamic double array, but does not have a copy constructor or assignment operator defined. Because of this, any time the copy constructor or assignment operator would be needed, the default action of copying the base address of the array over occurs, so multiple objects point to the same array.

Compile and run the program as given using the following commands:

g++ -g -o lab5 list.cpp
./lab5
Your output should appear similar to the following (without the color coding, which I've added to facilitate the discussion below, also your addresses may differ from the addresses given):
Report and value of a (empty list):
array pointer address=0x0 count=0 cap=0


Report and value of b (6 values from array 1):
array pointer address=0x727010 count=10 cap=10
4.5 6.5 2.3 1.2 6.2 9.8 0 0 0 0

Report and value of c (6 values from array 2):
array pointer address=0x727070 count=15 cap=15
5.2 4.3 7.1 8.5 3.7 2.8 0 0 0 0 0 0 0 0 0

Report and value for the clone of c (copy constructor):
array pointer address=0x727070 count=15 cap=15
5.2 4.3 7.1 8.5 3.7 2.8 0 0 0 0 0 0 0 0 0

Report and value of a after using a = c (assignment operator):
array pointer address=0x727070 count=15 cap=15
5.2 4.3 7.1 8.5 3.7 2.8 0 0 0 0 0 0 0 0 0

Report and value of a after using a = b (assignment operator):
array pointer address=0x727010 count=10 cap=10
4.5 6.5 2.3 1.2 6.2 9.8 0 0 0 0
*** glibc detected *** ./lab5: double free or corruption (top): 0x0000000000727070 ***
======= Backtrace: =========
/lib/libc.so.6[0x7f26d8f709a8]
/lib/libc.so.6(cfree+0x76)[0x7f26d8f72ab6]
./lab5(__gxx_personality_v0+0x2d4)[0x400e8c]
./lab5[0x4012f0]
/lib/libc.so.6(__libc_start_main+0xe6)[0x7f26d8f1b1a6]
./lab5(__gxx_personality_v0+0x51)[0x400c09]
======= Memory map: ========
00400000-00402000 r-xp 00000000 fe:07 253406                             /home/fac/melissa/public_html/cs222-w11/lab5
00601000-00602000 rw-p 00001000 fe:07 253406                             /home/fac/melissa/public_html/cs222-w11/lab5
00727000-00748000 rw-p 00727000 00:00 0                                  [heap]
7f26d4000000-7f26d4021000 rw-p 7f26d4000000 00:00 0 
7f26d4021000-7f26d8000000 ---p 7f26d4021000 00:00 0 
7f26d8efd000-7f26d9047000 r-xp 00000000 fe:00 54664                      /lib/libc-2.7.so
7f26d9047000-7f26d9246000 ---p 0014a000 fe:00 54664                      /lib/libc-2.7.so
7f26d9246000-7f26d9249000 r--p 00149000 fe:00 54664                      /lib/libc-2.7.so
7f26d9249000-7f26d924b000 rw-p 0014c000 fe:00 54664                      /lib/libc-2.7.so
7f26d924b000-7f26d9250000 rw-p 7f26d924b000 00:00 0 
7f26d9250000-7f26d9266000 r-xp 00000000 fe:00 54688                      /lib/libgcc_s.so.1
7f26d9266000-7f26d9466000 ---p 00016000 fe:00 54688                      /lib/libgcc_s.so.1
7f26d9466000-7f26d9467000 rw-p 00016000 fe:00 54688                      /lib/libgcc_s.so.1
7f26d9467000-7f26d94e9000 r-xp 00000000 fe:00 42508                      /lib/libm-2.7.so
7f26d94e9000-7f26d96e8000 ---p 00082000 fe:00 42508                      /lib/libm-2.7.so
7f26d96e8000-7f26d96ea000 rw-p 00081000 fe:00 42508                      /lib/libm-2.7.so
7f26d96ea000-7f26d97db000 r-xp 00000000 fe:02 573568                     /usr/lib/libstdc++.so.6.0.10
7f26d97db000-7f26d99da000 ---p 000f1000 fe:02 573568                     /usr/lib/libstdc++.so.6.0.10
7f26d99da000-7f26d99e0000 r--p 000f0000 fe:02 573568                     /usr/lib/libstdc++.so.6.0.10
7f26d99e0000-7f26d99e3000 rw-p 000f6000 fe:02 573568                     /usr/lib/libstdc++.so.6.0.10
7f26d99e3000-7f26d99f6000 rw-p 7f26d99e3000 00:00 0 
7f26d99f6000-7f26d9a12000 r-xp 00000000 fe:00 54655                      /lib/ld-2.7.so
7f26d9bff000-7f26d9c02000 rw-p 7f26d9bff000 00:00 0 
7f26d9c0d000-7f26d9c11000 rw-p 7f26d9c0d000 00:00 0 
7f26d9c11000-7f26d9c13000 rw-p 0001b000 fe:00 54655                      /lib/ld-2.7.so
7fff6dc55000-7fff6dc6a000 rw-p 7ffffffe9000 00:00 0                      [stack]
7fff6dc74000-7fff6dc75000 r-xp 7fff6dc74000 00:00 0                      [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted
Note the addresses in red and blue are the same, even though they are outputing separate objects. This is because the copy constructor and assignment operator are not defined, so the base address of c was just copied over to a and clone, rather than allocating new arrays for a and clone. Likewise, the base address of b was copied over when a = b was called.

Finally, note the long block of text that appears at the end of the program. When main() ends, all the objects created in main (a, b, c and clone) are destroyed. Since a and b point to the same array and c and clone point to the same array, you will end up trying to call delete [] array on the same memory address more than once. When this happens, the system aborts your code with this error message about "double free" (free is the C version of delete). This is another indication that the copy constructor and assignment operators have not properly been defined.

Assignment

Your assignment is to fix all of these problems by defining the assignment operator and copy constructor, as discussed in class. Recall that both functions will allocate an array based on the size of the source array and copy the elements from the source array into their newly allocated space. Also remember that the assignment operator must deal with the possibility of being assigned to itself and must delete any existing array before allocating a new one.

When you have properly defined the assignment operator and copy constructor, recompile the code and run it again. You should now see different memory addresses for all the spots highlighted in red and blue above. Additionally, the "double free" error message in green should be gone.

Email me the source code for your corrected list.cpp that has the assignment operator and copy constructor defined.