Segmentation fault - passage de fonction

#include <stdio.h>

void f1(int **t)
{
printf("entree fonction\n");
printf("%d %d\n",t[0][0],t[0][1]);
printf("%d %d\n",t[1][0],t[1][1]);
printf("%d %d\n",t[2][0],t[2][1]);
printf("fin fonction\n");
}

int main()
{
 int triangle[2][3][2];
 triangle[0][0][0] = 10;
 triangle[0][0][1] = 20;
 triangle[0][1][0] = 30;
 triangle[0][1][1] = 40;
 triangle[0][2][0] = 50;
 triangle[0][2][1] = 60;
 f1((int **)triangle[0]);
 return 0;
}

Je fais un projet ou j’ai ce problème, histoire d’être le plus clair, j’ai mis une version simple du problème.
En fait j’ai un tableau de triangles, et je dois envoyer à une fonction un des triangles du tableau.
Normalement j’ai une structure triangle, qui contient 3 pixel et une stucture pixel qui contient 2 entiers, on peut donc caster un triangle en tableau de 6 entiers.
Et le problème est lorsque je passe un triangle en argument d’une fonction, je n’arrive plus à l’utiliser après…
Merci de m’éclairer :slight_smile:

Ah … la joie du passage par pointeur :slight_smile:

En revanche, si je vire le cast, j’ai un joli message :

test.c:21: warning: passing arg 1 of `f1’ from incompatible pointer type

Si je fais ça :

void f1(int t[3][2])
{
printf("entree fonction\n");
printf("%d %d\n",t[0][0],t[0][1]);
printf("%d %d\n",t[1][0],t[1][1]);
printf("%d %d\n",t[2][0],t[2][1]);
printf("fin fonction\n");
}

int main()
{
 int triangle[2][3][2];
 triangle[0][0][0] = 10;
 triangle[0][0][1] = 20;
 triangle[0][1][0] = 30;
 triangle[0][1][1] = 40;
 triangle[0][2][0] = 50;
 triangle[0][2][1] = 60;
 f1(triangle[0]);
 return 0;
}

L’explication est assez conne, et le warning aurait du te faire tilter :

Si tu fais int x[n][m][p], cela veut dire que tu alloues un espace de sizeof(int)nm*p et qui est contigüe, d’accord?

Si tu fais x[i][j][k] = 3, quand tu déclares x comme int*** x, cela revient normalement à faire :

(((x+i)+j)+k) = 3;

Sauf que dans ton cas, tu ne fais pas du tout ça! Tu dis “je fais un tableau d’éléments contigües”, sauf que dans ce cas, le compilateur a besoin de connaitre les dimensions de tes sous tableaux, soit :

void f1(int t[][2])
{
printf("entree fonction\n");
printf("%d %d\n",t[0][0],t[0][1]);
printf("%d %d\n",t[1][0],t[1][1]);
printf("%d %d\n",t[2][0],t[2][1]);
printf("fin fonction\n");
}

Car dans ce cas là, il ne fait pas l’opération suscitée plus haut, il fait ça :

int x[n][m][p] = {…};
x[i][j][k] <=> x + (i*m+j)*p+k;

Pourquoi cela?

Tout simplement parce que la représentation n’est pas la même! (nombre contigüe).

Si tu veux plus simple, il s’agit juste de représenter ton tableau sous forme d’éléments contigüe, et de savoir réindexer a[i][j][k] dans un tableau à une seule dimension. Quand tu n’en as que deux, c’est simple :

int a[4][3] = {
  {1, 2, 3},
  {4, 5, 6},
  {7, 8, 9},
  {10, 11, 12}
};

Cela reste assez évident que a[i][j] <=> (a + 3i + j). Ici, ce sont des nombres, mais tu pourrais stocker autre chose, genre un … tableau, et dans ce cas, il faut prendre en compte la taille de chaque élément du premier tableau imbriqué, de taille sizeof(int)*2 dans mon exemple :

int a[4][3][2] = {
  {{0, 0}, {0, 0}, {0, 0}},
  {{0, 0}, {0, 0}, {0, 0}},
  {{0, 0}, {0, 0}, {0, 0}},
  {{0, 0}, {0, 0}, {0, 0}}
};

Ce qui fait :

a[i][j][k] = <=> a + (3*i + j)*2 + k.

Voilà…

(j’ai du en rajouter une couche, car j’ai du réapprendre ces formules, … au passage, tu n’es pas forcé de stocker les tableaux dans cet ordre, je ne crois cependant pas que cela dépende du compilateur - ils doivent être cohérents - mais dans les cas où tu convertis un tableau à deux dimensions vers un à une dimension, c’est plus si vrai … je te laisse lire ça : en.wikipedia.org… )
Edité le 13/05/2009 à 00:31

Merci beaucoup :slight_smile: