L'autre approche consisterait à allouer un bloc de mémoire contigu comprenant un bloc d'en-tête pour les pointeurs vers des lignes ainsi qu'un bloc de corps pour stocker les données réelles dans des lignes. Ensuite, marquez simplement la mémoire en affectant des adresses de mémoire dans le corps aux pointeurs de l’en-tête, ligne par ligne. Cela ressemblerait à ceci:
int** 2dAlloc(int rows, int* columns) {
int header = rows * sizeof(int*);
int body = 0;
for(int i=0; i<rows; body+=columnSizes[i++]) {
}
body*=sizeof(int);
int** rowptr = (int**)malloc(header + body);
int* buf = (int*)(rowptr + rows);
rowptr[0] = buf;
int k;
for(k = 1; k < rows; ++k) {
rowptr[k] = rowptr[k-1] + columns[k-1];
}
return rowptr;
}
int main() {
// specifying column amount on per-row basis
int columns[] = {1,2,3};
int rows = sizeof(columns)/sizeof(int);
int** matrix = 2dAlloc(rows, &columns);
// using allocated array
for(int i = 0; i<rows; ++i) {
for(int j = 0; j<columns[i]; ++j) {
cout<<matrix[i][j]<<", ";
}
cout<<endl;
}
// now it is time to get rid of allocated
// memory in only one call to "free"
free matrix;
}
L'avantage de cette approche est la libération élégante de mémoire et la possibilité d'utiliser une notation de type tableau pour accéder aux éléments du tableau 2D résultant.