tableau de caractères multi-dimensionnel?

Ce que j’essaie de faire est de créer un tableau 2D de chaînes de caractères.

void add2(char***b, char *i) { if (!i) { b[0][0] = (char*) malloc(120); sprintf(b[0][0], "%s", "hithere"); b[0][1] = (char*) malloc(120); sprintf(b[0][1], "%s", "bithere"); } else { strcat(b[0][0], "\\\\"); strcat(b[0][0], i); strcat(b[0][1], "\\\\"); strcat(b[0][1], i); } } void add1(char ***b) { add2(b,NULL); add2(b,"one"); add2(b,"two"); add2(b,"three"); } int main() { char **keys[2] = {0}; int i,j; add1(keys); for (i = 0; keys[i]; i++) for (j = 0; keys[j]; j++) { fprintf(stderr, "%s\n", keys[i][j]); free(keys[i][j]); } } 

Lorsque vous déclarez les clés du tableau, vous indiquez au compilateur que vous souhaitez utiliser un tableau de 2 pointeurs sur des pointeurs sur des caractères et lui demander d’initialiser ces pointeurs sur un pointeur vers NULL. Tout va bien .

Ensuite, vous appelez add1() . Tout va bien .

Ensuite, vous appelez add2() et essayez de placer dans le premier élément de b[0] la valeur malloc() par malloc() . Mais la valeur de b[0] est NULL. La valeur NULL a été définie dans la fonction main() . b[0] n’a pas d’éléments!

Lorsque vous avez des tableaux de tableaux (de tableaux …) sous la forme de pointeurs, vous devez malloc() (et free() ) à chaque niveau individuellement.


modifier

 #include  int main() { char **keys[2] = {0}; keys[0] = malloc(20 * sizeof *keys[0]); /* 20 ssortingngs */ keys[1] = malloc(20 * sizeof *keys[1]); /* 20 ssortingngs */ for (int k=0; k<20; k++) { keys[0][k] = malloc(120); /* string with 119 chars + '\0' */ keys[1][k] = malloc(120); /* string with 119 chars + '\0' */ } /* use k[0][0] through k[0][19] */ /* use k[1][0] through k[1][19] */ for (int k=0; k<20; k++) { free(keys[0][k]); free(keys[1][k]); } free(keys[0]); free(keys[1]); return 0; } 

Je mets tout dans la fonction main() , mais c'est la même idée si les malloc() s et free() s ont leur propre fonction.

La procédure générale pour l’allocation dynamic d’un tableau 2D de char * ressemble à ceci (pour tout autre type T, remplacez char * par le type souhaité):

 char ***new2DArr(size_t rows, size_t cols) { char ***newArr = NULL; size_t i; newArr = malloc(sizeof *newArr * rows); if (newArr) { for (i = 0; i < rows; i++) { newArr[i] = malloc(sizeof *newArr[i] * cols); if (newArr[i]) { /* initialize or assign newArr[i][0] - newArr[i][cols-1] here */ } } } return newArr; } 

Cela suppose que vous sachiez à l'avance combien de lignes et de colonnes vous souhaitez. Notez que vous avez alloué une table de pointeurs. vous devrez toujours allouer de la mémoire pour chaque entrée de chaîne, comme ceci:

 char **myArr = new2DArr(10, 10); myArr[0][0] = malloc(strlen("Hello, World") + 1); if (myArr[0][0]) { strcpy(myArr[0][0], "Hello, World"); } 

Si vous souhaitez append de nouvelles lignes ou de nouvelles entrées aux lignes existantes, vous devrez effectuer une comptabilité supplémentaire.

Voici un exemple qui étend une seule ligne:

 char **extendRow(char **row, char *newEntry, size_t *numEnsortinges) { char **tmp = realloc(row, *numEnsortinges + 1); if (tmp) { row = tmp; row[*numEnsortinges] = malloc(strlen(newEntry) + 1); if (row[*numEnsortinges]) { strcpy(row[*numEnsortinges], newEntry); (*numEnsortinges)++; } } return row; } 

Et vous l'appelez comme

 table[i] = extendRow(table[i], "This is a test", &entryCount); 

Le résultat est atsortingbué à la table[i] dans l'éventualité où la valeur du pointeur serait modifiée par realloc() . Je le fais de cette façon au lieu de passer un pointeur à la table [i] simplement pour limiter la gymnastique au pointeur.