bool** array_2d_bool;
char** array_2d_char;
These are not 2D arrays and cannot be used at pointing at 2D arrays. At best they can be used to point at the first element of an array of pointers.
And the only reason why you would want to use an array of pointers is when you want a lookup table, where each pointed-at type has different length, such as a string lookup table or a chained hash table. This isn't the case here, you just want a 2D array.
Using pointer-to-pointer for allocating a 2D array dynamically is always wrong, for multiple reasons: it doesn't create an actual array (so you can't use memcpy() and similar on it), it involves complex allocation/freeing that potentially leads to leaks, it causes heap segmentation and slower allocation, it gives poor cache performance and so on.
Instead allocate a 2D array:
malloc( sizeof(bool[x][y] );
Then point at it with an array pointer.
bool (*array_2d_bool)[x][y] = malloc( sizeof(bool[x][y] );
For ease of use, it is however much more convenient to point at the first array in this array of arrays, rather than pointing at the whole 2D array. So change it to this:
bool (*array_2d_bool)[y] = malloc( sizeof(bool[x][y] );
Now you can use it as array_2d_bool[i][j]
.
And when you are done, free it:
free(array_2d_bool);