C - Tableau à deux dimensions - de pointeurs

Bonjour à tous !

Je dois créer un tableau à deux dimensions de pointeurs (d’une structure que j’ai créé).

Ma structure se nomme ainsi : pile.

Mon tableau à deux dimensions se nomme grille.
J’ai déclaré ainsi : pile*** grille;

Cependant je n’arrive pas à allouer correctement la mémoire car lorsque j’ajoute des éléments dans grille et que je fais un affichage de grille le programme plante avant d’avoir afficher la totalité de son contenu.

Comment faut-il déclarer - allouer - attribuer un tableau à deux dimensions de pointeurs de structures???

D’avance merci :jap:

Une méthode générale (n = nombre de ligne, m = nombre de rangée, ie: pile[n-1][m-1] = élément en bas à droite.


struct pile*** pile_alloc(unsigned int n, unsigned int m) {
struct pile*** p = (pile***) calloc(n, sizeof(pile**));
if (p == NULL) return NULL; // erreur

for (unsigned int i = 0; i < n; ++i) {
  if (NULL == (p[i] = (pile**) calloc(m, sizeof(pile*)))) {
    // erreur on doit tout libérer
    for (unsigned int j = 0; j < i; ++j) {
      free(p[j]);
    } 
    free(p);
    return NULL;
  } 
}
return p;
}

Tu as d’autres méthodes, plus futée, mieux pour des matrices de petites tailles (en gros, parce qu’avoir des zones contiguës trop trop grande n’est pas forcément bien) : ça s’appelle le row/column major mode (je sais jamais lequel c’est, ça dépend de la façon dont tu stockes les données dans ta matrice, soit en ligne, soit en colonne, là ça doit être en colonne si je me plante pas) :

struct pile* p = calloc(nm, sizeof(struct pile*));

Et pour l’accès, ça doit se faire ainsi :

p[i*m+j]

Au niveau des types :

p = struct pile** 
p[i*m+j] = *(p+i*m+j) = struct pile*

Alors qu’avant ça se faisait ainsi :

p[i][j]

Ici, si tu prends les types :

p : struct pile***
p[i] = *(p+i) = struct pile**
p[i][j] = *(*(p+i)+j) = struct pile*

Mais es-ce que ceci:

p[i][j]

N’est pas identique à ceci:

p[i*m+j] 

J’en avais la conviction quand j’ai commencé à lire ce topic, mais elle s’est dissipée petit-à-petit lors de ma lecture…

Serait-ce tout de même juste?

Pour moi, c’est la même chose :neutre:
Mais comme l’a dit Sans-Nom, cela dépend de la façon dont tu stockes tes données : en ligne ou en colonne.

Non. p[i][j] ce n’est pas la même chose. Du moins, si tu prend rien que les types ça ne peut pas l’être. Ne serait-ce que parce que le compilateur ne connaît pas la dimension du premier tableau (vu que c’est dynamique).

Donc p[i][j] il va avoir du mal à le remplacer par p[i*m+j]. Par contre, ce qu’il fait dans le cas que j’ai montré, c’est : ((p+i)+j), ce qui n’est pas la même chose que (p+im+j).

Maintenant, j’ai un doute aussi. Faudrait faire un test voir si en row/column major c’est équivalent, mais j’en doute fortement, car au niveau pointeur, ça ne l’est pas du tout.

ok merci bien pour vos réponses ! :super:

Oui en fait, c’est équivalent dans ce cas là :


#define n 3
#define m 3
int x[n][m] = {0};
unsigned int i = 1, j = 1;
x[i][j] = 1;
fprintf(stdout, "*(x+i*m+j) = %d", *(x+i*m+j)));

Car c’est ce que fait le compilateur puisqu’il connaît la taille du tableau interne. Dans l’autre cas, ce sont des pointeurs, pas des tableaux, même si c’est vu comme des tableaux :slight_smile: