[C] Perte de référence & pointeurs
Bonjour,
Une petite question pour les pro du C. J'utilise la librairie gsoap et je dois créer les arguments de mes appels.
Je pensais avoir bien compris les mécanismes entourant les struct, les pointeurs, les références, les pointeurs de struct, etc... mais finalement je me heurte au problème suivant :
Voici les traces obtenues :
3 appairages à envoyer =>
#### - Appairage théorique 1 de : 006 / 0622222222
#### - Appairage théorique 1 de : 005 / 0611111111
#### - Appairage théorique 1 de : 004 / +33622222222
#### - Appairage théorique 2 de : 004 / +33622222222
#### - Appairage effectif de : 004 / +33622222222
#### - Appairage théorique 2 de : 004 / +33622222222
#### - Appairage effectif de : 004 / +33622222222
#### - Appairage théorique 2 de : 004 / +33622222222
#### - Appairage effectif de : 004 / +33622222222
On voit que au moment de mon appairage effectif (LOG 3), tous les pointeurs de mon tableau théorique inputNumList ont été modifiés entre la première boucle (LOG 1) et la deuxième (LOG 2).
Quelqu'un serait susceptible de m'expliquer le pourquoi ?
Merci d'avance,
oBo.
Une petite question pour les pro du C. J'utilise la librairie gsoap et je dois créer les arguments de mes appels.
Je pensais avoir bien compris les mécanismes entourant les struct, les pointeurs, les références, les pointeurs de struct, etc... mais finalement je me heurte au problème suivant :
struct ns1__num_USCOREassoc<br />{<br /> char *index; /* required element of type xsd:integer */<br /> char *numero; /* required element of type xsd:string */<br />};<br /><br />struct array_USCOREof_USCOREnum_USCOREassoc<br />{<br /> struct ns1__num_USCOREassoc **__ptr;<br /> int __size;<br />};<br /><br />//inputNums est un NSDictionnary initialisé avant...<br />//...<br />struct ns1__num_USCOREassoc *inputNumList[[inputNums count]];<br />int i=0;<br />NSLog(@"%d appairages à envoyer => ", [inputNums count]);<br />for(id key in inputNums) {<br /> struct ns1__num_USCOREassoc temp;<br /> temp.numero = (char*)[[inputNums objectForKey:key] UTF8String];<br /> temp.index = (char*)[(NSString*)key UTF8String];<br /> inputNumList[i] = &temp;<br /> NSLog(@"#### - Appairage théorique 1 de : %s / %s", inputNumList[i]->index, inputNumList[i]->numero); //NSLOG 1<br /> i++;<br />}<br />synchro_list.__size = [inputNums count]; // synchro_list est un objet de type array_USCOREof_USCOREnum_USCOREassoc<br />synchro_list.__ptr = inputNumList; // synchro_list est un objet de type array_USCOREof_USCOREnum_USCOREassoc<br />for(int i=0;i<[inputNums count];i++) {<br /> NSLog(@"#### - Appairage théorique 2 de : %s / %s", inputNumList[i]->index, inputNumList[i]->numero); //NSLOG 2<br /> NSLog(@"#### - Appairage effectif de : %s / %s", synchro_list.__ptr[i]->index, synchro_list.__ptr[i]->numero); //NSLOG 3<br />}
Voici les traces obtenues :
3 appairages à envoyer =>
#### - Appairage théorique 1 de : 006 / 0622222222
#### - Appairage théorique 1 de : 005 / 0611111111
#### - Appairage théorique 1 de : 004 / +33622222222
#### - Appairage théorique 2 de : 004 / +33622222222
#### - Appairage effectif de : 004 / +33622222222
#### - Appairage théorique 2 de : 004 / +33622222222
#### - Appairage effectif de : 004 / +33622222222
#### - Appairage théorique 2 de : 004 / +33622222222
#### - Appairage effectif de : 004 / +33622222222
On voit que au moment de mon appairage effectif (LOG 3), tous les pointeurs de mon tableau théorique inputNumList ont été modifiés entre la première boucle (LOG 1) et la deuxième (LOG 2).
Quelqu'un serait susceptible de m'expliquer le pourquoi ?
Merci d'avance,
oBo.
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
De même, inputNumList = &temp; va mettre la même adresse dans chaque élément du tableau du coup...
il faut donc allouer un ns1__num_USCOREassoc à chaque itération. (Et ne pas oublier, plus tard, de libérer la mémoire allouée quand elle n'est plus utilisée).
Autre problème, il faut faire des copies des chaines retournées par UTF8String pour éviter les problèmes (surtout si inputNums est détruit en fait)... Et détruire les copies quand elles ne sont plus utilisées.
Ca doit donner ça en gros:
Et attention, tu prends également l'adresse de la variable locale inputNumList pour l'affecter à synchro_list.__ptr, ce qui te garantira un plantage à coup sur dès que tu utiliseras synchro_list.__ptr en dehors de cette fonction, car à ce moment cela pointera sur un tableau qui n'existe plus...
Il va falloir réviser sérieusement la notion de pointeurs en C, d'après moi
Quoiqu'il en soit tout fonctionne, j'ai du remplacer la ligne
par
Autrement il me sortait une erreur conversion to non-scalar type requested.
Merci pour la rapidité de ta réponse.
Parce que j'aurais du écrire
(struct ns1__num_USCOREassoc *)malloc(sizeof(struct ns1__num_USCOREassoc))
Pourrait-il y avoir des problèmes si on ne met pas le pointeur devant le malloc ?
Tout au plus un warning selon le niveau de warning activé lors de la compilation (parce que le type de retour de la fonction malloc est "void *").
La bonne écriture est
Le seul cas où l'absence de cast entraà®ne un warning dans un programme C c'est lorsque l'on n'inclut pas la bibliothèque stdlib.h car alors le prototype implicite de malloc renvoie un int et non un void *. Mais l'erreur en ce cas est l'absence du #include <stdlib.h>, pas l'absence du cast.
Dans un projet XCode les bibliothèques standards comme stdlib.h sont incluses automatiquement, ce problème ne se pose pas.
Mais je le répète devant un malloc, on ne met pas de cast.