Yes, it is definitely possible. But you'll have to do more.
You have an array of void
s named toto
:
void *toto = malloc(8 * sizeof(char *) * 8);
In other words - toto
is a pointer to a piece of memory containing 8 * sizeof(char *) * 8
voids - you've probably thought that because computation suggests it is an array of pointers, the compiler will figure it itself.
It won't - what a compiler sees is something like this:
void *toto = malloc(64);
therefore you'll end up with a 1-dimensional "flat" array where each element is a void
.
Now you cast it:
char **tata = (char **)toto;
and it's all good so far. Now you have tata
which points to an array of pointers to char arrays which is not initialized. The type of tata[5]
is *char
.
So when you do:
tata[5][5] = 'a';
you're:
- accessing that array of pointers (
tata
) - ok
- accessing 6th (indexing from 0) pointer
tata[5]
- ok
- but
tata[5]
is not initialized and contains either NULL or some garbage
- acessing 6th element of
*tata[5]
- SEGFAULT
, because it's not valid pointer
What you must do is:
- initialize
toto
to how many "rows" you need in resulting matrix
- manually create all those end arrays yourself
So it could look like this:
void *toto = malloc(8 * sizeof(char *)); /* assuming 8 rows */
char **tata = (char **)toto;
int i;
for (i = 0; i < 8; i++) {
tata[i] = (char*)malloc(8 * sizeof(char)); /* assuming 8 columns */
}
tata[5][5] = 'a'; /* all is well now */
Which would compile and run without SEGFAULT.
I also suggest doing the cast before malloc and using constants for numbers of rows and columns, which will give us this:
int num_rows = 8;
int num_cols = 8;
char **tata = (char**)malloc(num_rows * sizeof(char*));
int i;
for (i = 0; i < num_rows; i++) {
tata[i] = (char*)malloc(num_cols * sizeof(char));
}
tata[5][5] = 'a';