//PROFESSORS CODE
constint SIZE = 5;
char* counts[SIZE];
// Allocate arrays in dynamic memory
for (int i = 0; i < SIZE; i++) {
counts[i] = newchar[SIZE - (i + 1)]; //suppose to print*****
for (int j = 0; j <= SIZE - (i + 1); j++) { // ****
cout << i << endl; // ***
counts[i][j] = 'X'; // **
} // *
}
// Print all counts
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j <= SIZE - (i + 1); j++) {
cout << counts[i][j];
}
cout << endl;
}
// Deallocate the rows
for (int i = 0; i < SIZE; i++) {
delete[] counts[i];
}
//VERSUSES
//MY CODE
constint SIZE = 5;
char* counts[SIZE];
// Allocate arrays in dynamic memory
for (int i = 0; i < SIZE; i++) {
counts[i] = newchar[SIZE - i]; //pointer at i = 0: size is 5-0 = 5, Each cell has X
for (int j = 0; j < SIZE - i; j++) { //pointer at i = 1: size is 5-1 = 4
cout << i << endl;counts[i][j] = 'X'; //pointer at i = 2: size is 5-2 = 3
} //pointer at i = 3: size is 5-3 = 2
} //pointer at i = 3: size is 5-3 = 1
// WHY 2D ARRAY? i is the position of the pointer in the char array and
// j is the position of the cells in the allocated array
// Print all counts
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE-i; j++) {
cout << counts[i][j];
}
cout << endl;
}
// Deallocate each pointer
for (int i = 0; i < SIZE; i++) {
delete[] counts[i]; // pointers are allocated arrays so we need (delete[])
}//then after delete we want to delete every pointer in the array
No, I’m not :-) It seems I was missing something, indeed.
(I would have started by a C-style array of 5, so the indexes from 0 to 4 looked fine to me, but I didn’t notice the code actually allocated an array of 4.)
My bad, my bad...
The prof's code, run through valgrind.
$ valgrind ./a.out
==8410== Memcheck, a memory error detector
==8410== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==8410== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==8410== Command: ./a.out
==8410==
0
0
0
0
0
==8410== Invalid write of size 1
==8410== at 0x400A22: main (bar.cpp:15)
==8410== Address 0x5ab6c84 is 0 bytes after a block of size 4 alloc'd
==8410== at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8410== by 0x4009D2: main (bar.cpp:12)
==8410==
1
1
1
1
2
2
2
3
3
4
==8410== Invalid read of size 1
==8410== at 0x400A64: main (bar.cpp:22)
==8410== Address 0x5ab6c84 is 0 bytes after a block of size 4 alloc'd
==8410== at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8410== by 0x4009D2: main (bar.cpp:12)
==8410==
XXXXX
XXXX
XXX
XX
X
==8410==
==8410== HEAP SUMMARY:
==8410== in use at exit: 72,704 bytes in 1 blocks
==8410== total heap usage: 7 allocs, 6 frees, 73,738 bytes allocated
==8410==
==8410== LEAK SUMMARY:
==8410== definitely lost: 0 bytes in 0 blocks
==8410== indirectly lost: 0 bytes in 0 blocks
==8410== possibly lost: 0 bytes in 0 blocks
==8410== still reachable: 72,704 bytes in 1 blocks
==8410== suppressed: 0 bytes in 0 blocks
==8410== Rerun with --leak-check=full to see details of leaked memory
==8410==
==8410== For counts of detected and suppressed errors, rerun with: -v
==8410== ERROR SUMMARY: 10 errors from 2 contexts (suppressed: 0 from 0)