[C] char** et &char*

char** et &char* [C] - C++ - Programmation

Marsh Posté le 19-06-2002 à 08:50:59    

J'avais jamais fait attention mais je me suis rendu compte que ce n'est pas tout à fais la même chose !!!

Code :
  1. void fct(char** chaine)
  2. {
  3. char* chaine_fct=NULL;
  4. chaine_fct=(char*)malloc(sizeof(char) * toto);
  5. [...]
  6. (*chaine)=chaine_fct;
  7. }
  8. char*  chaine1=NULL;
  9. char** chaine2=NULL;
  10. fct(&chaine1);
  11. fct(chaine2); /* CoreDump !!! */


 
En fait j'ai compris hier que lors de la declaration du "char*" une "case memoire" est allouee pour contenir l'adresse de la chaîne alors qu'avec le "char**", rien n'est alloué.
 
C'est logique mais j'avais jamais eu à le faire avant !!!


Message édité par darkoli le 04-07-2002 à 12:36:38

---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
Reply

Marsh Posté le 19-06-2002 à 08:50:59   

Reply

Marsh Posté le 19-06-2002 à 09:37:21    

DarkOli a écrit a écrit :

J'avais jamais fait attention mais je me suis rendu compte que ce n'est pas tout à fais la même chose !!!

Code :
  1. void fct(char** chaine)
  2. {
  3. char* chaine_fct=NULL;
  4. chaine_fct=(char*)malloc(sizeof(char) * toto);
  5. [...]
  6. (*chaine)=chaine_fct;
  7. }
  8. char*  chaine1=NULL;
  9. char** chaine2=NULL;
  10. fct(&chaine1);
  11. fct(chaine2); /* CoreDump !!! */


 
En fait j'ai compris hier que lors de la declaration du "char*" une "case memoire" est allouee pour contenir l'adresse de la chaîne alors qu'avec le "char**", rien n'est alloué.
 
C'est logique mais j'avais jamais eu à le faire avant !!!  




 
NON !!!
 
char * : tu déclares un pointeur sur une zone mémoire d'un octet.
 
char ** : tu déclares un pointeur sur un char * .
 
Et ensuite (d'après ce que je lis de ta "fonction void"  :??: ), là tu fais n'importe quoi : fct(&chaine1) va changer la valeur *chaine1 car il peut accéder à cette adresse (que tu ne connais pas; elle est gérée par le compilo);  
Alors que fct(chaine2) va tenter de changer la valeur contenu à l'adresse NULL !!! (qui est une adresse réservée !!!)
Dans les deux cas précédents, seuls les pointeurs sont crées !
Des plus ta "fonction" est telle que rien ne permet de dire que la zone mémoire allouée sera conservée lors de l'éxecution.


Message édité par zi_ril_wanou le 19-06-2002 à 09:40:02

---------------
Get the Cooool... Get the cool shoe-shine !
Reply

Marsh Posté le 19-06-2002 à 09:47:22    

char ** une case est allouée pour contenir l'adresse d'une case qui contiendra elle-même l'adresse d'un char


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 19-06-2002 à 10:26:56    

antp a écrit a écrit :

char ** une case est allouée pour contenir l'adresse d'une case qui contiendra elle-même l'adresse d'un char  




pas mieux :D


---------------
Le Tyran
Reply

Marsh Posté le 21-06-2002 à 01:28:35    

J'aurais écrit ça comme ça:

Code :
  1. void fct(char** ptrptrChaine){ //recevoir un char* par adresse
  2. char* ptrChaine="EFGH"; //"EFGH" alloué statiquement
  3. *ptrptrChaine=ptrChaine; //modifier le char* dont on a reçu l'adresse pour pointer sur "EFGH"
  4. }
  5. int main(){
  6. char*  ptrChaine1=NULL; //pointeur (sur char) initialisé à 0
  7. char** ptrChaine2=NULL; //pointeur (sur pointeur sur char) initialisé à 0
  8. fct(&ptrChaine1); //Bien:    transmettre l'adresse d'un (char* vallant 0)
  9. fct( ptrChaine2); //mauvais: transmettre 0 comme l'adresse d'un (char* n'existant pas)
  10. return 0;
  11. }

En faisant abstraction des const éventuels...
 
char** et &char* sont un même type, mais ils n'ont pas la même valeur ici.
 

zi_ril_wanou a écrit a écrit :

De plus ta "fonction" est telle que rien ne permet de dire que la zone mémoire allouée sera conservée lors de l'éxecution.


Ben si, tant qu'on fait pas free().
Ou alors tu veux dire qu'elle risque d'être perdue si on change le pointeur?
 
PS: faut plus utiliser [code] mais [cpp]


Message édité par Musaran le 22-06-2002 à 01:22:15

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 24-06-2002 à 21:42:16    

musaran a écrit a écrit :

J'aurais écrit ça comme ça:

Code :
  1. void fct(char** ptrptrChaine){ //recevoir un char* par adresse
  2. char* ptrChaine="EFGH"; //"EFGH" alloué statiquement
  3. *ptrptrChaine=ptrChaine; //modifier le char* dont on a reçu l'adresse pour pointer sur "EFGH"
  4. }
  5. int main(){
  6. char*  ptrChaine1=NULL; //pointeur (sur char) initialisé à 0
  7. char** ptrChaine2=NULL; //pointeur (sur pointeur sur char) initialisé à 0
  8. fct(&ptrChaine1); //Bien:    transmettre l'adresse d'un (char* vallant 0)
  9. fct( ptrChaine2); //mauvais: transmettre 0 comme l'adresse d'un (char* n'existant pas)
  10. return 0;
  11. }

En faisant abstraction des const éventuels...
 
char** et &char* sont un même type, mais ils n'ont pas la même valeur ici.
 
Ben si, tant qu'on fait pas free().
Ou alors tu veux dire qu'elle risque d'être perdue si on change le pointeur?
 
PS: faut plus utiliser [code] mais




 

Code :
  1. char ptrChaine[]="EFGH";


 
C mieu ;) (c peut être plus ccosmétique qu'autrechose mais ça choque moin l'oeuil)


Message édité par LetoII le 24-06-2002 à 21:42:43

---------------
Le Tyran
Reply

Marsh Posté le 24-06-2002 à 22:47:39    

letoII a écrit a écrit :

 
 

Code :
  1. char ptrChaine[]="EFGH";


 
C mieu ;) (c peut être plus ccosmétique qu'autrechose mais ça choque moin l'oeuil)




 
Je pense que c'est une question d'habitude. J'ai toujours écrit "char* ptrChaine='EFGH";" et utiliser "[]" me choque car je ne l'ai jamais utilisé.


---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
Reply

Marsh Posté le 25-06-2002 à 12:43:48    

et si je veux faire un truc du genre
 

Code :
  1. fct("blabla" );


 
faut déclarer comment le parametre de la fonction?

Reply

Marsh Posté le 25-06-2002 à 13:34:47    

void fct(char *) passe mais je te conseil un void fct(const char*) (ça évite de faire des conneries à l'interrieure de la fonction)


---------------
Le Tyran
Reply

Marsh Posté le 25-06-2002 à 13:40:03    

prq un const?

Reply

Marsh Posté le 25-06-2002 à 13:40:03   

Reply

Marsh Posté le 25-06-2002 à 13:43:37    

si tu fait un appel comme ça:

Code :
  1. fct("chaine bidon" );


 
Mieu vaut ne aps modifier la chaine passée en argument, d'où le const, le compilo vérifie que tu ne modifie pas la chaine dans ta fonction. Ca signale à celui qui l'utilise que la fonction ne modifie pas la chaîne passée en argument.


---------------
Le Tyran
Reply

Marsh Posté le 25-06-2002 à 13:48:39    

ok ok :jap:

Reply

Marsh Posté le 26-06-2002 à 01:33:19    

xmulder a écrit a écrit :

et si je veux faire un truc du genre

Code :
  1. fct("blabla" );

faut déclarer comment le parametre de la fonction?



Puisque, dès qu'on mentionne un tableau, on ne récupère q'un pointeur sur son 1er élément, char[] est (presque) identique à char*.
 
La recommendation est de déclarer de la façon dont on compte s'en servir.

Code :
  1. char fct(const char*  ptr){ //le vrai type du paramètre reçu
  2. return *(ptr+1);
  3. }
  4. char fct(const char[] tab){//variante synonyme
  5. return tab[1];
  6. }


Message édité par Musaran le 02-07-2002 à 00:25:40

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 26-06-2002 à 08:14:40    

pour info en général les compilo remplace tab[i] par *(tab+i). Au passage tab[i] fait strictement la même chose que i[tab]? en effet rien ne distingue *(tab+i) de *(i+tab) :D


---------------
Le Tyran
Reply

Marsh Posté le 26-06-2002 à 08:50:49    

letoII a écrit a écrit :

pour info en général les compilo remplace tab[i] par *(tab+i). Au passage tab[i] fait strictement la même chose que i[tab]? en effet rien ne distingue *(tab+i) de *(i+tab) :D




 
et le type de variable pointée?
si i et tab ne sont pas du meme type, je pense q tu risq d'avoir des surprises non?

Reply

Marsh Posté le 26-06-2002 à 08:54:41    

letoII a écrit a écrit :

pour info en général les compilo remplace tab[i] par *(tab+i). Au passage tab[i] fait strictement la même chose que i[tab]? en effet rien ne distingue *(tab+i) de *(i+tab) :D




 
mais ça ne fonctionne qu'avec des char ce truc.
parce que pour un tableau d'entier, tab[i] est équivalent a *(tab+4*i) et non pas *(tab+i) (sous réserve qu'un entier soit codé sur 4 octets).

Reply

Marsh Posté le 26-06-2002 à 08:58:26    

non ça marche pour tout type de variables par ceque l'arithmétique sur les pointeur est particulière.
Quelque soit ton type de variable tab[i] est strictement équivalent *(tab + i). Maintenent pour le type une fois compilé ça pose pas de pb, par contre ça peux ne pas pas passer la vérification de type. tout dépend du code à côté.


---------------
Le Tyran
Reply

Marsh Posté le 26-06-2002 à 09:04:44    

je suis d'accord avec pitounet.  
TYPE !
 
encore q ton truc puisse pe passer avec certains compilateurs, ok mais je suis sur q sur certaines plateforme ca te jette si i n'est pas dans un espace memoire q tu peux accéder.

Reply

Marsh Posté le 26-06-2002 à 09:37:04    

non
Ca passe quelque soit la plateforme par ce que c la façon standard d'implémenter la chose
 
Y a qu'à la vérification de type que ça peut ne pas marcher.


Message édité par LetoII le 26-06-2002 à 09:37:38

---------------
Le Tyran
Reply

Marsh Posté le 26-06-2002 à 23:45:54    

Je confirme lettoII : tab[i] signifie *(tab+i), c'est spécifié dans la norme du C/C++.
 
Bienvenue dans l'arithmétique des pointeurs:

Code :
  1. int tab[16] ;
  2. int* ptrA = &tab[6] ;
  3. ptrA+1 ; //n'ajoute pas 1 à l'adresse ptrA, mais sizeof(int), générant l'adresse de l'int suivant en mémoire (tab[7]).
  4. ptrA-1 ; //beaucoup moins courant, génére l'adresse de l'int précédent en mémoire (tab[5]).
  5. int* ptrB = &tab[8] ;
  6. ptrB-ptrA ; //peu connu, donne le nombre d'int séparant les deux emplacements pointé (2).
  7. ptrA-ptrB ; //même principe, mais résultat négatif (-2).


Message édité par Musaran le 26-06-2002 à 23:48:35

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 27-06-2002 à 01:26:11    

je suis d'accord. :jap:
mais si tes 2 pointeurs ne sont pas du meme type, ca coince non?

Reply

Marsh Posté le 27-06-2002 à 08:19:30    

Ben si tu fais une différence de pointeurs de type différent ça pose un pb (sauf transtypage des vecteur). D'autant plus que ça n'a pas nécessairement un sens.


---------------
Le Tyran
Reply

Marsh Posté le 27-06-2002 à 23:17:41    

Si les 2 pointeurs ne pointent pas le même type, c'est une erreur, ça n'a pas de sens.
 
Si les 2 pointeurs ne pointent pas des éléments du même tableau, le résultat est indéfini, a cause d'adresses mémoire pas nécessairement multiples de la taille du type pointé.
 
Faire la somme de 2 pointeurs n'a pas de sens.
 
Voilà, c'est les bases...


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 29-06-2002 à 12:25:50    

Au fait pour info, j'ai essayé ça sous windows:
 

Code :
  1. unsigned char tab1[1024*1024];
  2. bool          tab2[1024*1024];


 
Et j'ai eu un chouette stack Overflow. Comme quoi l'allocation statique c pas forcément térible quand on veut gérer des grosses données (2 MO c quand même pas si gros).
 
A méditer


---------------
Le Tyran
Reply

Marsh Posté le 29-06-2002 à 15:25:29    

letoII a écrit a écrit :

Au fait pour info, j'ai essayé ça sous windows:
 

Code :
  1. unsigned char tab1[1024*1024];
  2. bool          tab2[1024*1024];


 
Et j'ai eu un chouette stack Overflow. Comme quoi l'allocation statique c pas forcément térible quand on veut gérer des grosses données (2 MO c quand même pas si gros).
 
A méditer




 
Moi j'ai déjà un double tab[8000000]; et ça marche sans problèmes !!!


---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
Reply

Marsh Posté le 29-06-2002 à 15:29:41    

letoII a écrit a écrit :

Au fait pour info, j'ai essayé ça sous windows:
Et j'ai eu un chouette stack Overflow. Comme quoi l'allocation statique c pas forcément térible quand on veut gérer des grosses données (2 MO c quand même pas si gros).
A méditer




 
Ben si chaque programme devait allouer plus de 2Mo par defaut pour la pile, ca serait un gros gachis
Apres, je crois que tu peux dire a ton compilo d'allouer une tailler plus grande pour la pile...

Reply

Marsh Posté le 30-06-2002 à 01:07:20    

euh justes une petite question la, ca fait combien de temps que vous faites de la programmation?(c pas pour me vanter c au contraire parce que je suis impressionné)
merci de me repondre.

Reply

Marsh Posté le 30-06-2002 à 10:33:00    

3 ans (dont les deux dernières années de façon intensive :) )


---------------
Le Tyran
Reply

Marsh Posté le 30-06-2002 à 10:34:52    

letoII a écrit a écrit :

Au fait pour info, j'ai essayé ça sous windows:
 

Code :
  1. unsigned char tab1[1024*1024];
  2. bool          tab2[1024*1024];


 
Et j'ai eu un chouette stack Overflow. Comme quoi l'allocation statique c pas forcément térible quand on veut gérer des grosses données (2 MO c quand même pas si gros).
 
A méditer




 
Désolé ct pas le bon topic :D


---------------
Le Tyran
Reply

Marsh Posté le 01-07-2002 à 16:42:46    

bailly33 a écrit a écrit :

euh justes une petite question la, ca fait combien de temps que vous faites de la programmation?(c pas pour me vanter c au contraire parce que je suis impressionné)
merci de me repondre.




 
7 ans environ.


---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
Reply

Marsh Posté le 01-07-2002 à 17:28:27    

letoII a écrit a écrit :

3 ans




 
Tu double réponds ?


---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
Reply

Marsh Posté le 01-07-2002 à 18:25:02    

Oups, persuadé que j'avais pas répondu :)


---------------
Le Tyran
Reply

Marsh Posté le 02-07-2002 à 00:32:07    

bailly33 a écrit a écrit :

euh justes une petite question la, ca fait combien de temps que vous faites de la programmation?(c pas pour me vanter c au contraire parce que je suis impressionné)
merci de me repondre.



Depuis longtemps, mais sérieusement depuis 1 an seulement.
 
Encore à propos de l'arithmétique des pointeurs:
-Ça ne marche pas avec des pointeurs de fonctions (pas des sens).
-En cas de tableau mutidimension (int tab[2][3]), seule la première dimension est assimilable à un pointeur (int* tab[3]).


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 02-07-2002 à 09:01:44    

musaran a écrit a écrit :

 
Depuis longtemps, mais sérieusement depuis 1 an seulement.
 
Encore à propos de l'arithmétique des pointeurs:
-Ça ne marche pas avec des pointeurs de fonctions (pas des sens).
-En cas de tableau mutidimension (int tab[2][3]), seule la première dimension est assimilable à un pointeur (int* tab[3]).




 
Pour les pointeurs de fonctions ça doit marcher si t'as un tableau de pointeur de fonction, non?


---------------
Le Tyran
Reply

Marsh Posté le 03-07-2002 à 02:05:35    

letoII a écrit a écrit :

Pour les pointeurs de fonctions ça doit marcher si t'as un tableau de pointeur de fonction, non?



Avec des pointeurs sur les cellules du tableau, oui.
Mais pas avec les pointeurs de fonction eux-mêmes.
 
J'ai pas essayé avec des pointeurs sur membres  :pt1cable: .


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 03-07-2002 à 07:23:31    

Ben de toute manière faire des opérations sur des pointeurs en dehors d'un espace mémoire contiguë (tableau quoi) ça n'a guère de sens.


---------------
Le Tyran
Reply

Marsh Posté le 04-07-2002 à 00:11:31    

Sache, petit scarabé, qu'en matière de bogues l'imagination humaine est sans limites :jap: .


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 04-07-2002 à 08:41:02    

musaran a écrit a écrit :

Sache, petit scarabé, qu'en matière de bogues l'imagination humaine est sans limites :jap: .




 
Et plus tu as de l'experience plus tu fais des bogues (malgré toi) difficiles à identifier.


---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
Reply

Marsh Posté le 05-07-2002 à 01:59:49    

Hmm...
Bogues évoluées, codeur évolué ?
 
Le thème m'inspire et je fais un topic "Trouvez le bogue".


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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