[C] pointeur et chaine de caractère

pointeur et chaine de caractère [C] - C - Programmation

Marsh Posté le 10-01-2008 à 20:57:15    

Slt , voila je debute en C et j'ai un probleme , en faite je voudrais modifier la valeur du pointeur *p dans une fonction  et retrouver la nouvelle valeur dans le main() .
Voila mon code :  

Code :
  1. void fonc(char* p) {
  2. printf("fonction , p = %s\n",p);
  3. p = "b";
  4. printf("fonction , apres modif , p = %s\n",p);
  5. }
  6. int main(int argc,char *argv[]) {
  7. char *p = "a";
  8. printf("main , p = %s\n",p);
  9. fonc(p);
  10. printf("main , après la fonction p = %s\n",p);
  11. return EXIT_SUCCESS;
  12. }


Seulement la valeur change dans la fonction mais pas dans le main() ... ma question comment faire? ou si vous auriez de la documentation sur les pointeur de chaine de caractere ... .
Merci
++

Reply

Marsh Posté le 10-01-2008 à 20:57:15   

Reply

Marsh Posté le 10-01-2008 à 21:06:43    

1/ il faut utiliser un pointeur de pointeur
2/ pr copier ta chaien, il faut utiliser strcpy

 
Code :
  1. void fonc(char** p)
  2. {
  3.   printf("fonction , p = %s\n",*p);
  4.   strcpy(*p,"b" );
  5.   printf("fonction , apres modif , p = %s\n",*p);
  6. }
  7. int main(int argc,char *argv[])
  8. {
  9.   char *p = "a";
  10.   printf("main , p = %s\n",p);
  11.   fonc(&p);
  12.   printf("main , après la fonction p = %s\n",p);
  13.   return EXIT_SUCCESS;
  14. }


Message édité par Joel F le 10-01-2008 à 21:07:00
Reply

Marsh Posté le 10-01-2008 à 21:17:03    

Ouaip , c exactement se que je voulais :) en plus maintenent je c qu il faut que je cherche de la doc sur les pointeur de pointeur , donc un double merci :)

Reply

Marsh Posté le 10-01-2008 à 22:50:57    

Y'a pas à chercher de doc, c'est un pointeur normal... Qui pointe vers un pointeur.

Reply

Marsh Posté le 11-01-2008 à 08:20:37    

Comme au départ on a
char *p = "a";
donc en mémoire non modifiable je crois, je ne suis pas sûr que faire
strcpy(*p, "b" );
fonctionne sur tous les systèmes.

Message cité 1 fois
Message édité par Trap D le 11-01-2008 à 08:20:59
Reply

Marsh Posté le 11-01-2008 à 08:52:02    

char* je vois pas pourquoi ca serait non modifiable.
const char* ok, mais char* :|

Reply

Marsh Posté le 11-01-2008 à 09:22:52    

C'est strcpy(p, "b" ), pas *p.
*p c'est le caractère 'a'.

Reply

Marsh Posté le 11-01-2008 à 10:25:29    

Attentio, on dans la fonction  
void fonc(char** p)
donc c'est bien strcpy(*b, "b" );

Reply

Marsh Posté le 11-01-2008 à 11:02:47    

Trap D a écrit :

Comme au départ on a  
char *p = "a";  
donc en mémoire non modifiable je crois, je ne suis pas sûr que faire  
strcpy(*p, "b" );  
fonctionne sur tous les systèmes.


 
je pense surtout que "b" est alloué dans la pile de la fonction et sera donc détruit à la fin de la fonction, il faut onc mettre "b" dans la mémoire dynamique.
Ce n'est pas mieux de faire ?
 

Citation :


free(*p);  
*p=strdup("b" );

Message cité 2 fois
Message édité par ffomnislash le 11-01-2008 à 11:03:10
Reply

Marsh Posté le 11-01-2008 à 11:22:52    

Oh la la. [:psychokwak]
 
Or donc, comme l'a dit Joel F :

char *p  = "a";


p est en réalité un const char *, et une modification de p entraine un comportement indéfini. Généralement ça se termine en coredump.
 
Ensuite :


 
free() ?  
Où as-tu vu une quelconque allocation de cette variable ? [:mullet]
Dans le code présenté ci-dessus, c'est coredump.
 
Bref, soit vous passez par un tableau de char à taille fixe, soit faut faire une allocation dynamique.

Reply

Marsh Posté le 11-01-2008 à 11:22:52   

Reply

Marsh Posté le 11-01-2008 à 14:08:05    

pour modifier char *p "a"; il faut le faire une allocation dynamique , sinon char *a = "a" aura ue taille fixe de 1 caracteraire donc pour y maitre plus il faudrais faire  
char *p = malloc(200 * sizeof (char))
et la on a de l espace pour maitre encore quelque caractere .
C est sa ou je dis n importe quoi?

Reply

Marsh Posté le 11-01-2008 à 14:09:37    

C'est ça, sauf que faire un malloc() sur une taille fixe n'est pas très utile, autant définir char p[200].


Message édité par Elmoricq le 11-01-2008 à 14:09:49
Reply

Marsh Posté le 11-01-2008 à 17:35:07    

mr_tonks a écrit :

Slt , voila je debute en C et j'ai un probleme , en faite je voudrais modifier la valeur du pointeur *p dans une fonction  et retrouver la nouvelle valeur dans le main() .
<...>
Seulement la valeur change dans la fonction mais pas dans le main()  


Erreur classique
 
http://mapage.noos.fr/emdel/notes. [...] e_variable


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 11-01-2008 à 17:38:16    

Joel F a écrit :

char* je vois pas pourquoi ca serait non modifiable.
const char* ok, mais char* :|


Rappel :  


char *p = "a";
strcpy(*p, "b" );  


Déjà, c'est pas *p, mais p :  

strcpy(p, "b" );


p pointe sur une chaine non modifiable "a";
On ne peut rien écrire à cette emplacement. Le comportement est indéfini, c'est un bug.
 
Ceci est correct :  


char s[] = "a";
strcpy(s, "b" );  


Ceci aussi :  


char *p = "a";
p =  "b";


;)
 
Mais pour éviter les erreurs, je recommande que les pointeurs vers des chaines littérales soient définis 'au contenu non modifiable' :  


char const *p = "a";
p =  "b";


Une option de gcc permet de s'en assurer :  

-Wwrite-strings


 comme rappelé ici : http://mapage.noos.fr/emdel/codage.htm#cfg_compilo


Message édité par Emmanuel Delahaye le 11-01-2008 à 17:42:47

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 11-01-2008 à 17:44:56    

Trap D a écrit :

Attentio, on dans la fonction
void fonc(char** p)
donc c'est bien strcpy(*b, "b" );


Oui, dans ce contexte tordu précis... Je recommande de retourner la valeur du pointeur  (comme fait malloc() ;) ) plutôt que de se casser la tête avec des pointeurs de pointeurs...

 

Enfin, moi, je suis pas maso...

Message cité 1 fois
Message édité par Emmanuel Delahaye le 11-01-2008 à 17:49:12

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 11-01-2008 à 17:46:29    

Emmanuel Delahaye a écrit :


Enfin, moi, je suis pas maso...


 
Je repondais dans le context, je susi bien d'accord avec ton post N-1

Reply

Marsh Posté le 11-01-2008 à 17:46:39    

ffomnislash a écrit :

je pense surtout que "b" est alloué dans la pile de la fonction et sera donc détruit à la fin de la fonction,


Mais qu'est-ce que tu racontes... Une chaine littérale a une durée de vie égale à celle du processus.
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 11-01-2008 à 17:47:48    

Elmoricq a écrit :


Où as-tu vu une quelconque allocation de cette variable ? [:mullet]


Dans sa logique (strdup()), c'est cohérent !


Message édité par Emmanuel Delahaye le 11-01-2008 à 17:50:39

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 11-01-2008 à 18:06:53    

En écrivant char *p = NULL dans main() alors. [:dawa]

Reply

Marsh Posté le 17-01-2008 à 20:10:33    

Emmanuel Delahaye a écrit :


Mais qu'est-ce que tu racontes... Une chaine littérale a une durée de vie égale à celle du processus.
 


 
les chaines leterales sont allouées où alors ? elles sont détruites quand ?
 
sinon oui, le free c'est par habitude, ca evite des fuites mémoires

Reply

Marsh Posté le 17-01-2008 à 21:25:22    

ffomnislash a écrit :


 
les chaines leterales sont allouées où alors ? elles sont détruites quand ?
 
sinon oui, le free c'est par habitude, ca evite des fuites mémoires

Si tu as une déclaration de la forme char *p = "abc"; ta chaine est dans le .data segment.
Comme ces notions ne t'on pas l'air familiere, j'ai cherché un peu une explication relativement claire.  
La ça a l'air pas trop mal, vas voir la section Z.3 http://www.tenouk.com/ModuleZ.html
 
Quand je dis que c'est dans le .data segment, c'est le cas sur les anciens formats binaires exécutables, quoi qu'il n'y ait pas de norme définie sur la question (il me semble avoir vu qu'on pouvait avoir aussi le cas de compilos allouant ces chaines dans une partie speciale du text segment, a coté du code machine, ce qui a un certain sens, le contenu du .text segment n'étant en principe pas modifiable. Et ca explique tres bien la survenue d'une segmentation error si on tente de modifier une telle chaine. Le .data segment etant read-write, sur les anciens compilos, il s'avere qu'on pouvait parfois modifier une chaine en principe constante).
Sur des formats binaires executables plus récents, on trouve une section rodata, soit read-only data, qui convient parfaitement, et qui est intégrée au .text segment
La durée de vie de ces chaines est la durée de vie du programme, puisqu'elles ne resident pas dans la partie dynamique de la mémoire du programme.
A+,


Message édité par gilou le 17-01-2008 à 22:27:34

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 18-01-2008 à 12:03:59    

oki merci, je ne connaissait pas la presence du data segment, on en apprend tous les jours :D

Reply

Marsh Posté le 19-01-2008 à 19:45:18    

ffomnislash a écrit :

oki merci, je ne connaissait pas la presence du data segment, on en apprend tous les jours :D


N'en tire pas de conclusions trop hâtives et surtout non portables. Le langage C est plus vague que ça mais le principe est clair :  
 
http://mapage.noos.fr/emdel/notes.htm#donnees
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 19-01-2008 à 21:25:58    

Emmanuel Delahaye a écrit :


N'en tire pas de conclusions trop hâtives et surtout non portables. Le langage C est plus vague que ça mais le principe est clair :  
 
http://mapage.noos.fr/emdel/notes.htm#donnees
 


 
hehe merci, j'ai eu des cours de compilation en faite, je sais comment ca fonctionne la zone avec le code, la zone dynamique (malloc/free) ainsi que la gestion de la pile par les procédures (d'une manière général).
En faite j'avais eu des problèmes en faisant un retour d'une chaine (return "hehe" ), j'avais donc suppose que les chaines étaient allouées le temps de la procédure. Mais en réalité elles sont donc présentes pendant toute l'exécution du processus et le problème venait du fait que la modification soit interdite.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed