Pb avec la modification d'un pointeur dans une fonction

graphtyrael Messages postés 12 Date d'inscription dimanche 22 décembre 2002 Statut Membre Dernière intervention 18 juillet 2006 - 24 mars 2005 à 16:43
cleter Messages postés 92 Date d'inscription mardi 25 février 2003 Statut Membre Dernière intervention 15 mai 2006 - 25 mars 2005 à 21:14
Bonjour à tous!

Pour un projet que je suis actuellement entrain de finaliser j'ai besoin de modifier dans une fonction un pointeur de caractères passé en argument de celle-ci :

void fct_x(char * pt_modif)
{
free(pt_modif);
pt_modif = (char*) malloc(1*sizeof(char));

//Remplissage de pt_modif avec un \0 à la fin en agrandissant la zone allouée à chaque caractère saisi.

//====> ICI tout marche, pt_modif contient bien ma chaine de caractère.

return;
}

int main()
{
char * pt_main;

pt_modif = (char*) malloc(1*sizeof(char));

fct_x(pt_main);

//=====> ICI pt_main ne contient que \0 (???)

return 0;
}

Il est bien évidemment que ce code est un exemple de la situation .

Lors de l'appel de ma fonction dans le programme principal le pointeur pt_main contient une chaine de caractère.
Dans ma fonction fct_x, je désalloue la zone, donc pt_modif ne contient plus rien.
Je réalloue pt_modif, j'insert une chaine de caractère qui est bien présente à la fin de la fonction mais que je ne retrouve pas après l'appel de fonction dans le programme principal!

Voila ou est mon problème! Je ne pense pas faire de mauvaise manip et pour moi, tout devrait marcher.

Merci de vos réponse !

Graphy

6 réponses

cleter Messages postés 92 Date d'inscription mardi 25 février 2003 Statut Membre Dernière intervention 15 mai 2006
24 mars 2005 à 17:04
slt,

dans ton main ta mi:

pt_modif = (char*) malloc(1*sizeof(char));


je suppose que c'est une copier/coller de trop et que tu voulai mettre:


pt_main= (char*) malloc(1*sizeof(char));



et en se qui concerne ton pb: est-ce qu'a la fin de ta fct
fct_x tu désaloue la memoire?(question conne, mai on c jamais).



Heu, et puis je trouve ca un peu bizar, tu alloues un seul caractere pour stocké une chaine:
malloc(1*sizeof(char));

je pense que tu devrai mettre un truc du genre
malloc(255*sizeof(char));



je vai tenté de m'expliquer: quand tu fais un malloc, tu reserve une
certaine zone mémoire pour y mettre ce que tu veux, dans ton cas, tu
reserve un seul et unique caractere. Donc lorsque tu est dans ta
fonction, et que tu ecrit dans pt_modif ta chaine de caractere, en
realité, tu dépasse de la zone reservé par le malloc, et comme ton pc
est tolerant, il di rien. mais quand tu sor de cette fct pour revenir
dan le main, vu que tu n'as que le 1er octet de reservé, ton OS se
permet de réutilisé la zone mémoire ou tavai mi le reste de ta chaine.

Maintenant je t'avou que je ne sais pas pk tu te retrouve avec juste \0, jaurai plutot parié sur juste le 1er caractere.



tien nous au courrant
0
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
24 mars 2005 à 17:51
voici un exemple qui te fera comprendre ton erreur :

**********
soit une fct :
void Mul(int x)
{
x = x*2;
};
int main()
{
int val = 4;
Mul(val);
}

Tu es d'accord val ne vaudra pas 8 dans le main mais toujours 4 car tu lui as passé une valleur et pas un pointeur sur une valeur. Pour que ca marche il faut soit retourner le résultat soit passer un pointeur :
int Mul(int x);
{
return 2*x;
}
void Mul(int* x)
{
*x = (*x) * 2;
}

*******
Maintenant pour ton problème c'est le même raisonnement sauf que à la place de 'int' tu met 'char*'. Tu passe en effait un pointeur mais sur le début de la chaîne, pas l'adresse de la chaîne, il faut soit retourner une nouveau début de chaîne soit passer l'adresse d'une variable capable de stocker cette addresse (un char**)
char* fct_x(char * pt_modif)
{
...
return pt_modif;
}

void fct_x(char ** pt_modif)
{
*ptmodif = malloc(...);
}
0
cleter Messages postés 92 Date d'inscription mardi 25 février 2003 Statut Membre Dernière intervention 15 mai 2006
24 mars 2005 à 22:01
heu..ymca2003, t'est sur de ce que tu di la?
le pointeur qui pointe sur le début de la chaine, il contient bien
l'adresse de la chaine... et ton pointeur de pointeur, ca me parait
lourd...

alors, peu etre que j'ai rien compris, mais tu ma pas convaincu...
0
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
25 mars 2005 à 08:49
C'est clair que je me suis mal exprimé mais c'est pourtant comme ça qu'il faut faire.char* p malloc(32)>p contient l'adresse du premier caractère de la chaîne disons que cette adresse vaut 0x12345678.

tu passe cette adresse à la fonction void fct_x(char * pt_modif)
=> dans cette fonction, pt_modif vaudra donc 0x12345678.
Comme tu as l'adresse
du premier caractères, tu peux modifier les cractères de la chaîne, normal.

maintenant, dans cette fonction, tu réalloue une chaîne donc tu change la valeur de pt_modif.pt_modif malloc(...)> disons que pt_modif prend maintenant la valeur 0x34567890 nouvelle adresse du début de la chaîne.

Mainteant c'est la que le parallelle avec mon exemple du post précédent arrive.
pt_modif est d'accord un pointeur sur un char mais c'est aussi une variable locale. Etant un pointeur, tu peux modifier le contenu pointé (les caractères) mais si tu modifie sa valeur (l'adresse) tu n'as aucun moyen de la récupérer en sortie (comme quand tu fais x = 2*x) dans la première fonction. En sortie de la fonction l'adresse 0x34567890 est perdue.

Si tu veux modifier la valeur d'une variable par une fonction, il faut passer un pointeur. Toi tu veux modifier la valeur d'une adresse, il faut donc passer un pointeur sur une varaible capable de contenir une adresse et donc un pointeur double !

Voila pour l'explication. Maintenant passer un pointeur double c'est lourd, c'est pourquoi ta fonction de réallocation devrait plutot retourner la nouvelle adresse plutot que de modifier celle passer en paramètre.

Ta fonction est en fait du mêm genre que realloc qui prend en param l'ancien pointeur et renvoi le nouveau.
0

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

Posez votre question
graphtyrael Messages postés 12 Date d'inscription dimanche 22 décembre 2002 Statut Membre Dernière intervention 18 juillet 2006
25 mars 2005 à 11:44
Merci pour vos propositions de réponses...

J'ai posé la question à un de mes profs et apparemment un pointeur ne serait pas allouable dans un fonction. En effet : seule l'adresse/pointeur est transmis(e) et lors d'une réallocation, cette adresse change = > l'adresse de départ et l'adresse réallouée ne sont pas les même et le programme principal n'a pas de moyen de la connaitre .

Solution évoquée plus haut : fournir l'adresse d'un pointeur : un pointeur de pointeur!

Pour répondre à ymca2003 , le problème c'est que ma fonction retroune déjà un code d'erreur puisque celle-ci à pour fonction d'ouvrir un fichier.
C'est pour cela que je ne peux pas prévoir à l'avance (hors de la fonction) la taille dont j'aurais besoin et que je souhaite la modifier à l'interieur de ma fonction.

Voici l'originale :

Je précise que la fonction charger_texte() est la fonction qui réellement récupère le contenu du fichier "filename" et msg_box() est une petite fonction (à moi:)) qui crée un msg_box simple, oui/non ou editbox suivant l'argument 3 (les argument 1 et 2 étant respectivements le titre et le message de la message box et l'argument 4 un char** qui recoit le nom du pointeur à modifier lors d'un edit box.
Le problème réside entièrement à l'intérieur de cette fonction et de ce qu'elle revoit. Et a priori je vois pas ce qui m'empèche d'avoir le contenu du fichier dans "text". Mais cette fonction me renvoi à peu près n'importe quoi, tantot un seul caractère \0, tantot le début du fichier et une suite de caractères complètement incohérents ou bien encore tout va bien !

Si vous pouviez y jeter un petit coup d'oeil je vous en serais très reconnaissant !

int ouvrir(char **texte,char *filename)
{

int choix;
char *tmp;



if(msg_box("Ouvrir","Nom/Chemin de fichier",3,&filename)) //Saisie du nom du fichier à ouvrir
{
tmp = (char*) malloc(3300*sizeof(char)); //Allocation d'une grande zone de mémoire pouvant accueillir 3300 caractères au max.
if(choix charger_texte(filename,tmp)) //changer_text revoit un code d'erreur : 0 pas bon , 1=OK
{
free(*texte); //Libération de l'espace texte
*texte=(char*)malloc((strlen(tmp)+1)*sizeof(char)); //Réallocation de texte à la taille du contenu du fichier
strcpy(*texte,tmp); //Recopiage du temporaire dans le texte final


free(tmp); //Libération de la temporaire
}else
{
msg_box("Erreur","Erreur : l'ouverture a \202chou\202",0,&filename); //Affiche unmessage d'erreur, filename n'est pas utilisée!
}


}else
{
msg_box("Erreur","Erreur : Ouverture abandonn\202e",0,&filename); //Affiche unmessage d'erreur, filename n'est pas utilisée!
choix = 0;
}

return choix;
}

Voila !!!

Bonne Journée à tous!

Graphy
0
cleter Messages postés 92 Date d'inscription mardi 25 février 2003 Statut Membre Dernière intervention 15 mai 2006
25 mars 2005 à 21:14
ah oki, en faite je ne m'étais di que le malloc changeai l'adresse (ce
qui en faite est tout a fait logic)...et si je peu modifé mes chaine de
caractere en fesan comme ca, c'est parceke je n'allou pa la mémoir dans
la fonction

Mci pr les détail

@+
0
Rejoignez-nous