Atsortingbuer de la mémoire à un tableau 3D à l’aide d’un sortingple pointeur

Je dois atsortingbuer de la mémoire à un tableau 3D à l’aide d’un sortingple pointeur.

#include  int main() { int m=10,n=20,p=30; char ***z; z = (char***) malloc(sizeof(char**)*m*n*p); return 0; } 

Est-ce que c’est correct de faire ça? (Je pense que ce que je fais est incorrect.)

Pour allouer complètement un tableau dynamic 3D, vous devez procéder comme suit:

 #include  #include  int main() { int m=10,n=20,p=30; char ***z; z = malloc(m * sizeof(char **)); assert(z != NULL); for (i = 0; i < m; ++i) { z[i] = malloc(n * sizeof(char *)); assert(z[i] != NULL); for (j = 0; j < n; ++j) { z[i][j] = malloc(p); assert(z[i][j] != NULL); } } return 0; } 

La libération des données est laissée comme un exercice pour le lecteur.

Il n’est pas nécessaire de convertir la valeur de retour de malloc() , en C.

Et si vous prévoyez de stocker directement m * n * p caractères (et de calculer vous-même l’adresse), vous ne devez bien entendu pas redimensionner l’atsortingbution en fonction de la taille d’un caractère char ** .

Vous voulez dire:

 int m = 10, n = 20, p = 30; char *z = malloc(m * n * p * sizeof *z); 

Cela allouera 10 * 20 * 30 = 6000 octets. Cela peut être vu comme formant un cube de hauteur p , chaque “tranche” le long de l’axe vertical représentant n * m octets.

Comme il s’agit d’un adressage manuel, vous ne pouvez pas utiliser, par exemple, z[k][j][i] pour indexer, mais vous devez utiliser z[k * n * m + j * m + i] .

Si vous n’avez pas besoin que la mémoire soit allouée dans un seul bloc contigu (l’IME étant le cas habituel), procédez comme suit:

 char ***z; z = malloc(sizeof *z * m); // allocate m elements of char ** if (z) { int i; for (i = 0; i < m; i++) { z[i] = malloc(sizeof *z[i] * n); // for each z[i], if (z[i]) // allocate n elements char * { int j; for (j = 0; j < n;j++) { z[i][j] = malloc(sizeof *z[i][j] * p); // for each z[i][j], if (z[i][j]) // allocate p elements of char { // initialize each of z[i][j][k] } } } } } 

Notez que vous devrez libérer cette mémoire dans l'ordre inverse:

 for (i = 0; i < m; i++) { for (j = 0; j < n; j++) free(z[i][j]; free(z[i]); } free(z); 

Si vous avez vraiment besoin que la mémoire soit allouée dans un bloc contigu, vous avez plusieurs choix. Vous pouvez allouer un seul bloc et calculer vos compensations manuellement:

 char *z = malloc(sizeof *z * m * n * p); // note type of z! ... z[i * m + j * n + k] = some_value(); 

Lorsque vous avez terminé, il vous suffit de faire un seul free :

 free(z); 

Si vous avez un compilateur C99 ou un compilateur C11 qui prend en charge les tableaux de longueur variable, vous pouvez procéder de la manière suivante:

 int m=..., n=..., p=...; char (*z)[n][p] = malloc(sizeof *z * m); 

Cela déclare z comme un pointeur sur un tableau de caractères n x p , et nous allouons m tels éléments. La mémoire est allouée de manière contiguë et vous pouvez utiliser la syntaxe d'indexation de tableaux à 3 dimensions normale ( z[i][j][k] ). Comme pour la méthode ci-dessus, vous n'avez besoin que d'un seul appel free :

 free(z); 

Si vous ne disposez pas d'un compilateur C99 ou d'un compilateur C11 prenant en charge les VLA, vous devez créer des constantes de compilation n et p , telles que

 #define n 20 #define p 30 

sinon cette dernière méthode ne fonctionnera pas.

modifier

m n'est pas nécessaire que m soit une constante de compilation dans ce cas, juste n et p .

Vous auriez besoin de la boucle nestede suivante –

 z = (char**)malloc(sizeof(char*) * m); for (int i = 0; i < m; ++i) { *(z + i) = (char*)malloc(sizeof(char*) * n); for (int j = 0; j < n; ++j) { *(*(z + i)) = (char)malloc(p); } } 

Peut ne pas être synactiquement exact, mais cela devrait être quelque chose dans ce sens.

Vous voulez sizeof(char) non sizeof(char**) car ce dernier vous donnera la taille d’un pointeur qui, sur la plupart des systèmes modernes, sera de 4 octets au lieu du 1 attendu.