While you are free to declare and allocate for a array of pointers to char [tRows] and then loop allocating for each row, you can also declare a pointer to array of char [tRows] and allocate tRows
of them in a single call which provides the benefit of a single allocation and single free, e.g.
#include <iostream>
#include <iomanip>
#define tRows 10
int main (void) {
char (*chessboard)[tRows] = new char[tRows][tRows];
for (int i = 0; i < tRows; i++) {
for (int j = 0; j < tRows; j++) {
chessboard[i][j] = i + j;
std::cout << " " << std::setw(2) << (int)chessboard[i][j];
}
std::cout << '\n';
}
delete[] (chessboard);
}
Example Use/Output
$ ./bin/newdelete2d
0 1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 10
2 3 4 5 6 7 8 9 10 11
3 4 5 6 7 8 9 10 11 12
4 5 6 7 8 9 10 11 12 13
5 6 7 8 9 10 11 12 13 14
6 7 8 9 10 11 12 13 14 15
7 8 9 10 11 12 13 14 15 16
8 9 10 11 12 13 14 15 16 17
9 10 11 12 13 14 15 16 17 18
and, confirming your memory use:
$ valgrind ./bin/newdelete2d
==7838== Memcheck, a memory error detector
==7838== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==7838== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==7838== Command: ./bin/newdelete2d
==7838==
0 1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 10
2 3 4 5 6 7 8 9 10 11
3 4 5 6 7 8 9 10 11 12
4 5 6 7 8 9 10 11 12 13
5 6 7 8 9 10 11 12 13 14
6 7 8 9 10 11 12 13 14 15
7 8 9 10 11 12 13 14 15 16
8 9 10 11 12 13 14 15 16 17
9 10 11 12 13 14 15 16 17 18
==7838==
==7838== HEAP SUMMARY:
==7838== in use at exit: 0 bytes in 0 blocks
==7838== total heap usage: 2 allocs, 2 frees, 72,804 bytes allocated
==7838==
==7838== All heap blocks were freed -- no leaks are possible
==7838==
==7838== For counts of detected and suppressed errors, rerun with: -v
==7838== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)