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 copy/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 ./lab5Your 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 (10 values from array 1): array pointer address=0xea7010 count=10 cap=10 4.5 6.5 2.3 1.2 6.2 9.8 12.3 4.2 11.1 9.4 Report and value of c (6 values from array 2): array pointer address=0xea7050 count=6 cap=6 5.2 4.3 7.1 8.5 3.7 2.8 Report and value for the clone of c (copy constructor): array pointer address=0xea7050 count=6 cap=6 5.2 4.3 7.1 8.5 3.7 2.8 Report and value of a after using a = c (assignment operator): array pointer address=0xea7050 count=6 cap=6 5.2 4.3 7.1 8.5 3.7 2.8 Report and value of a after using a = b (assignment operator): array pointer address=0xea7010 count=10 cap=10 4.5 6.5 2.3 1.2 6.2 9.8 12.3 4.2 11.1 9.4 *** glibc detected *** ./lab5: double free or corruption (fasttop): 0x0000000000ea7050 *** ======= Backtrace: ========= /lib/libc.so.6(+0x71ad6)[0x7fd374169ad6] /lib/libc.so.6(cfree+0x6c)[0x7fd37416e84c] ./a.out[0x400fd9] ./a.out[0x4013b9] /lib/libc.so.6(__libc_start_main+0xfd)[0x7fd374116c4d] ./a.out[0x400be9] ======= Memory map: ======== 00400000-00402000 r-xp 00000000 fe:02 435135 /home/fac/melissa/cs222/lab5 00601000-00602000 rw-p 00001000 fe:02 435135 /home/fac/melissa/cs222/lab5 00ea7000-00ec8000 rw-p 00000000 00:00 0 [heap] 7fd370000000-7fd370021000 rw-p 00000000 00:00 0 7fd370021000-7fd374000000 ---p 00000000 00:00 0 7fd3740f8000-7fd374250000 r-xp 00000000 fe:00 54682 /lib/libc-2.11.2.so 7fd374250000-7fd37444f000 ---p 00158000 fe:00 54682 /lib/libc-2.11.2.so 7fd37444f000-7fd374453000 r--p 00157000 fe:00 54682 /lib/libc-2.11.2.so 7fd374453000-7fd374454000 rw-p 0015b000 fe:00 54682 /lib/libc-2.11.2.so 7fd374454000-7fd374459000 rw-p 00000000 00:00 0 7fd374459000-7fd37446f000 r-xp 00000000 fe:00 54654 /lib/libgcc_s.so.1 7fd37446f000-7fd37466e000 ---p 00016000 fe:00 54654 /lib/libgcc_s.so.1 7fd37466e000-7fd37466f000 rw-p 00015000 fe:00 54654 /lib/libgcc_s.so.1 7fd37466f000-7fd3746ef000 r-xp 00000000 fe:00 42525 /lib/libm-2.11.2.so 7fd3746ef000-7fd3748ef000 ---p 00080000 fe:00 42525 /lib/libm-2.11.2.so 7fd3748ef000-7fd3748f0000 r--p 00080000 fe:00 42525 /lib/libm-2.11.2.so 7fd3748f0000-7fd3748f1000 rw-p 00081000 fe:00 42525 /lib/libm-2.11.2.so 7fd3748f1000-7fd3749e7000 r-xp 00000000 fe:07 573470 /usr/lib/libstdc++.so.6.0.13 7fd3749e7000-7fd374be7000 ---p 000f6000 fe:07 573470 /usr/lib/libstdc++.so.6.0.13 7fd374be7000-7fd374bee000 r--p 000f6000 fe:07 573470 /usr/lib/libstdc++.so.6.0.13 7fd374bee000-7fd374bf0000 rw-p 000fd000 fe:07 573470 /usr/lib/libstdc++.so.6.0.13 7fd374bf0000-7fd374c05000 rw-p 00000000 00:00 0 7fd374c05000-7fd374c23000 r-xp 00000000 fe:00 42528 /lib/ld-2.11.2.so 7fd374e0a000-7fd374e0e000 rw-p 00000000 00:00 0 7fd374e1f000-7fd374e22000 rw-p 00000000 00:00 0 7fd374e22000-7fd374e23000 r--p 0001d000 fe:00 42528 /lib/ld-2.11.2.so 7fd374e23000-7fd374e24000 rw-p 0001e000 fe:00 42528 /lib/ld-2.11.2.so 7fd374e24000-7fd374e25000 rw-p 00000000 00:00 0 7fff77b21000-7fff77b36000 rw-p 00000000 00:00 0 [stack] 7fff77bff000-7fff77c00000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] AbortedNote 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.
Compile and run the code using
g++ -o lab5fixed list_fixed.cpp ./lab5fixedNote that the memory addresses for the clone of c and a after each assignment are now different than the original objects b and c.
Answer the following questions in the Moodle text box for this assignment: