Erreur pointeur vers tableau dynamique?

Résolu/Fermé
L1Student - 23 janv. 2013 à 17:59
 L1Student - 23 janv. 2013 à 20:47
Bonjour,

je rencontre un problème (surement avec une solution extrêmement simple, d'ailleurs) qui me bloque depuis hier soir.

Je travaille avec une série de fonctions, et j'ai une première fonction qui initialise un tableau 2 dimensions de manière dynamique.

void initialisation (int **Tab, int ligne, int colonne) {
int i;
int j;
int nbcellule;

Tab =calloc(ligne, sizeof (int*) );

for (i=0; i<colonne;i++)
Tab[i]=calloc(colonne, sizeof(int));
[...]
}
( J'ai retiré toute les affectations des valeurs du tableau, le code fait 70 lignes donc si possible autant éviter d'écrire un post trop long )

Je n'ai pas de warning ni d'erreur lors de la compilation.
Dans cette fonction, pour tester, j'ai fait une double boucle printf pour afficher le tableau, le tableau s'affiche bien. J'en déduis qu'il est bien généré

Mais j'ai l'impression que dès qu'on sors de la fonction initialisation, le tableau Tab ici généré n'est plus reconnu comme un tableau.
J'ai testé une double boucle printf pour afficher le tableau à l'écran dans le main après avoir appelé la fonction initialisation. Dès qu'on y arrive, le programme plante ( et pas d'erreur ou de warning à la compilation bien sur )

De la même manière, dans une autre fonction ( qui a pour but d'afficher tout simplement le tableau), je rencontre le même problème. prototype qui suit
void affiche (int **Tab, int ligne, int colonne) ;


Je ne vois pas d'ou viens l'erreur, du coup j'aimerais bien un coup de main pour m'aiguiller sur ce qui la cause. Voila la manière dont j'appelle les fonctions dans le main
int main() {
int ligne=0;
int colonne=0;
int **Tab=NULL;

dimensionnement (&ligne,&colonne); (juste pour faire scanf pour ligne et colonne )
initialisation (Tab,ligne,colonne);
affiche (Tab,ligne,colonne);

return 0;
}

Merci d'avance!

PS: je sais pas si j'ai été clair, un peu fatigué désolé ^^

6 réponses

Utilisateur anonyme
23 janv. 2013 à 18:08
Bonsoir

Un grand classique.
Quand tu appelles ta fonction initialisation, tu ne lui passes pas la variable Tab mais une copie qui contient la valeur de Tab (initialisée à NULL)
Ta fonction initialisation modifie cette copie, mais ne touche pas à la variable originale, celle du main.
Quand tu reviens dans le main, Tab est toujours NULL.

Si tu veux que ta fonction puisse modifier Tab, il faut lui passer l'adresse de Tab.
En conséquence, il faut aussi ajouter un * à chaque utilisation de Tab dans initialisation, (y compris dans la déclaration des paramètres)

C'est ce qu'on fait toujours pour les tableaux dynamiques de char (char *). Ça n'a l'air de poser de problème à personne, mais quand il d'agit d'un tableau de pointeurs, ça a l'air de beaucoup perturber les gens, alors que c'est strictement la même chose.
0
Donc si j'ai bien compris

Dans ma fonction initialisation, je remplace **Tab par ***Tab

dans le premier calloc je mets **Tab avec un sizeof(int*)
Dans le deuxieme calloc, *Tab avec sizeof(int)

et qu'à chaque fois que je veut modifier la valeur je mette *Tab?

( et dans mon main je mets &Tab du coup) ?

Parcequ'en faisait ça, mon programme plante toujours, mais dans initialisation cette fois ^^'
EDIT: cependant je suis pas au top de ma forme, j'ai peut être fait une nouvelle erreur dans mon programme sans même réaliser

EDIT 2:
initialisation (***Tab [...] )
[...]
*Tab=Calloc (x, sizeof(*int));

for [...]
Tab[i]=Calloc (y, sizeof(int))

Avec ça ca marche pour l'allocation on dirait. Par contre j'ai un nouveau problème au niveau de l'affectation ^^

for (i=0; i<cpt;i++) {
printf("ha"); // pour test la boucle
*Tab[Ttabx[i]][Ttaby[i]]=1;
}
le programme plante au niveau du *Tab
0
Utilisateur anonyme
23 janv. 2013 à 18:55
Je viens d'essayer, ça marche.
- initialisation (&Tab..) dans le main
- void initialisation (int ***Tab... dans la déclaration de la fonction
- (*Tab) [i]=calloc(colonne,.. dans la fonction : ne pas oublier les parenthèses ! Sinon le déréférencement des pointeurs n'est pas celui que tu crois.

Au passage, corrige
for (i=0; i<ligne;i++) 
(*Tab)[i]=calloc(colonne, sizeof(int)); 

Ça risque de devenir gênant si le tableau n'est pas carré.
0
Bon je change et je change partout du coup je sais plus ou j'en suis, et ça marche toujours pas ^^ :

CAS 1: je mets ***Tab, **Tab=Calloc, (*Tab)[i]=Calloc et ça plante dans l'initialisation
CAS 2: je mets ***Tab, *Tab Calloc, Tab[i], ca marche dans la fonction mais pas dehors
dans les deux cas, l'appel est fait avec &Tab dans le main

Dans les deux cas, aucun warning au niveau des pointeurs

du coup voila le programme en quasi entier selon votre suggestion, si vous voyez le problème ^^

void initialisation (int ***Tab, int ligne, int colonne) {   
    int i;   
    int j;   
    int nbcellule;   

    **Tab = calloc(ligne, sizeof (int*) );   

    for (i=0; i<ligne;i++)   
        (*Tab)[i]=calloc(colonne, sizeof(int));   


    int Ttabx[nbcellule]; // j'ai supprimé le code qui donne les valeurs de ce 
// tableau, étant donné que le programme n'arrive même pas au printf situé 
//avant celui ci. (supprimé juste dans le poste, hein :p)  
    int Ttaby[nbcellule]; // pareil   


    for (i=0; i<nbcellule;i++)    
        *Tab[Ttabx[i]][Ttaby[i]]=1;   
}   

0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Utilisateur anonyme
23 janv. 2013 à 20:29
Ton **Tab = calloc(ligne, sizeof (int*) ); , j'ai beaucoup de mal à y croire !

void initialisation (int ***Tab, int ligne, int colonne) {   
    int i;   
    int j;   
    int nbcellule;   

    (*Tab) = calloc(ligne, sizeof (int*) );   

    for (i=0; i<ligne;i++)   
        (*Tab)[i]=calloc(colonne, sizeof(int));   


    int Ttabx[nbcellule]; // j'ai supprimé le code qui donne les valeurs de ce 
// tableau, étant donné que le programme n'arrive même pas au printf situé 
//avant celui ci. (supprimé juste dans le poste, hein :p)  
    int Ttaby[nbcellule]; // pareil   

// la suite ne peut marcher que si Ttabx et Ttaby sont initialisés avec des valeurs allant de 0 à ligne-1 et de 0 à colonne-1
    for (i=0; i<nbcellule;i++)    
        (*Tab)[Ttabx[i]][Ttaby[i]]=1;   // et les parenthèses ?
}   
0
"Ton **Tab = calloc(ligne, sizeof (int*) ); , j'ai beaucoup de mal à y croire ! "
Moi aussi, je dois dire que j'y croyais pas. Maintenant, je comprends pourquoi ^^

Tout le problème venait effectivement de la parenthèse de
(*Tab)[Ttabx[i]][Ttaby[i]]=1;

Merci beaucoup pour ton temps le père, j'aurais au moins mieux compris les pointeurs de pointeurs (de pointeurs).

Je vais aller lire quelques cours pour mieux comprendre le déréférencement des pointeurs, mais en gros, au moins, j'ai compris pourquoi ça marchait pas!

Merci encore
0