A) w pierwszej kolejności tworzysz tablice wskaźników
B) potem do każdego wskaźnika(któremu pamięć przydzieliłeś w A) przydzielasz pamięć od odpowiednim rozmiarze.
Inny Przykład:
int rozmiar = 10;
int **tablica;
int dlugoscTab = 85;
tablica=malloc(rozmiar*sizeof(*tablica));
for(int i=0;i<rozmiar;i++)
{
tablica[i]=malloc(dlugosc*sizeof(**tablica));
}
powyższy kod można tak zapisać:
int rozmiar = 10;
int dlugoscTab = 85;
int * tablica[10];
for(int i=0;i<rozmiar;i++)
{
tablica[i]=malloc(dlugoscTab*sizeof(int));
}
czyli tak naprawdę tworzysz tablicę na 10 wskaźników - gdzie każdy wskaźnik wskazuje na tablicę o rozmiarze 85(typu int). Można to sobie wyobrazić jako tablicę wskaźników - gdzie do każdego wskaźnika podpięta jest(zwisa) tablica 85-elemntowa.
Gdybyś chciał ręcznie stworzyć powyższy przykład to najprościej napisałbyś po prostu:
int tablica[10][85]; . Powyższa konstrukcja jest bardzo przydatna gdy chcemy optymalnie wykorzystać pamięć.