Affectation de mémoire pour un tableau 2D contigu

J’essaie de créer une fonction générique qui, lorsqu’elle est appelée, alloue une mémoire contiguë à un tableau dimensionnel. L’objective est de réaliser quelque chose comme ci-dessous

entrez la description de l'image ici

donc pour y parvenir – l’équation que j’utilise est

Type **pArray; int total_elements = ((rows * cols) + rows); pArray = (Type **) malloc(total_elements * sizeof(Type)); 

Je suis également confus en ce qui concerne l’access aux éléments. J’ai du mal à visualiser comment le code ci-dessous remplira les éléments du tableau ci-dessus

 for (row = 0; row < dim0; ++row) { for (col = 0; col < dim1; ++col) { /* For this to work Type must be a 1D array type. */ for (ix = 0; ix < (int)(sizeof(item)/sizeof(item[0])); ++ix) { /* printf("%4d\n", testValue); */ ppObj[row][col][ix] = testValue; if (testValue == SCHAR_MAX) testValue = SCHAR_MIN; else ++testValue; } } } 

L’objective n’est pas de créer un format de tableau ci-dessous

entrez la description de l'image ici

Cela ne marchera pas. Vous supposez que votre Type * a la même taille que votre Type ce qui est généralement faux. Mais pourquoi avez-vous besoin des pointeurs de ligne? Ma première idée d’implémentation ressemblerait à ceci:

 typedef struct TypeArray { size_t cols; Type element[]; } TypeArray; TypeArray *TypeArray_create(size_t rows, size_t cols) { TypeArray *self = calloc(1, sizeof(TypeArray) + rows * cols * sizeof(Type)); self->cols = cols; return self; } 

ecrit getter et setter en utilisant par exemple self->element[row * self->cols + row] .

[edit]: Suite à cette discussion ici, c’est faisable comme ceci:

 typedef long long Type; Type **createArray(size_t rows, size_t cols) { size_t r; /* allocate chunk: rows times the pointer, rows * cols times the value */ Type **array = malloc(rows * sizeof(Type *) + rows * cols * sizeof(Type)); /* calculate pointer to first row: point directly behind the pointers, * then cast */ Type *row = (Type *) (array + rows); /* set all row pointers */ for (r = 0; r < rows; ++r) { array[r] = row; row += cols; } return array; } 

L'utilisation pourrait ressembler à ceci:

 int main() { Type **array = createArray(3, 4); for (int r = 0; r < 3; ++r) { for (int c = 0; c < 4; ++c) { array[r][c] = (r+1) * (c+1); } } for (int r = 0; r < 3; ++r) { for (int c = 0; c < 4; ++c) { printf("array[%d][%d] = %lld\n", r, c, array[r][c]); } } free(array); return 0; } 

Cela suppose qu'aucun type ne nécessite un alignement plus grand qu'un pointeur de données. Sinon, vous devrez calculer une quantité d'octets de remplissage à insérer après vos pointeurs. Pour plus de sécurité, vous pouvez utiliser le sizeof(Type) et certains calculs modulo (insérer les octets de remplissage à l'aide d'un pointeur char * ), mais cela gaspillerait beaucoup de mémoire si votre Type est par exemple une grosse struct .

Au total, cette tâche est écrite par un enseignant vraiment très désemparé.