Pointeur sur char*

SlimJ -  
Sugel Messages postés 4076 Date d'inscription   Statut Membre Dernière intervention   -
Bonjour,

voici un code:

char* ch1="aaaaaa";
char* ch2="bonjour";

strcpy(ch1,ch2);
printf("%s",ch1)



le code ne compile pas, le probléme reside au niveau de l'allocation mémoire de ch1.
ce que je comprends pas c'est pourquoi il ya pas de reservation mémoire de 7 cas a ch1 lorsqu'on fait
char * ch1="aaaaaaa"; 

normalement on reserve 7 case.
sinon, quelle est alors la difference en mémoire entre
char* ch1 et char* ch1="aaaaaa" 



2 réponses

Sugel Messages postés 4076 Date d'inscription   Statut Membre Dernière intervention   727
 
Pour allouer ces chaînes, ont doit utiliser cette syntaxe:
char chaine[] = "blablabla";


Je m'explique:
La syntaxe que tu utilise est dédiée à la déclaration de pointeurs, mais ne permet pas d'allouer en même temps de la mémoire pour une chaîne. La syntaxe ci dessus permet de faire les deux à la fois.

Attention, le type de la variable chaine déclarée ci-dessus est
char *
, et non pas
char
.

PS: tu pourrais faire un effort sur la forme, ton message tel qu'il est présenté ne donne pas envie d'y répondre: montrer que tu attends une réponse est important, c'est une des seules raisons qui pousse les gens à le faire.

------------------------------------------------------------------------------------
"La peur mène à la colère. La colère mène à la haine. Et la haine ... mène à la souffrance." - Yoda
0
Sugel Messages postés 4076 Date d'inscription   Statut Membre Dernière intervention   727
 
En effet, erreur de ma part, cette syntaxe est valide et crée un pointeur vers une chaîne dans un zone de mémoire non-inscriptible.

Ma réponse est donc fausse. Je suis encore passé pour un cong :c
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
Bonjour,

Je complémente la réponse de Sugel,

Tu peux aussi allouer avec un pointeur :
char *p=malloc(TAILLE);
strcpy(p,"coucou"); 


De plus attention à char *p="aaaaaaa";
Cela alloue un emplacement de 8 (et non 7) char mais dans une zone en lecture seule. Donc pas de modification possible. C'est pour ça qu'il est conseillé de l'utiliser avec un const.

Cdlt

Google is your friend
0
Sugel Messages postés 4076 Date d'inscription   Statut Membre Dernière intervention   727
 
diable, ma réponse est fausse :o
horreur et damnation.

Je ne savais pas cette syntaxe valide, merci (encore une fois) de ce complément appréciable.
Du coup, il faudrait que je voie comment est géré cet aspect lecture seule:
est-ce que la variable est stockée dans la section .code, ou bien dans une autre section ?

Il y a une autre nuance, plus importante encore :
la première syntaxe, avec les crochets, ne crée pas de véritable pointeur, mais est en fait un alias pour l'adresse du début de la chaîne, tandis que la seconde alloue réellement un pointeur désignant l'adresse de la chaîne.

Autrement dis, dans le premier cas, l'adresse de la chaîne est recopiée en dur à chaque fois, tandis que dans le second, c'est l'adresse d'un pointeur vers la chaîne qui est transcrite dans les opcodes.

Le seul usage à mon avis de la seconde syntaxe, moins utilisée car plus coûteuse en opcodes et en mémoire, est le détournement de l'adresse de la chaîne après compilation, ou bien définir une chaîne par défaut pour un paramètre potentiellement destiné à être modifié.

C'est vraiment passionnant ^^

As-tu une autre idée d'usage ?
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
est-ce que la variable est stockée dans la section .code, ou bien dans une autre section ?
Dans le segment .data plutôt (lecture seule).

la première syntaxe, avec les crochets, ne crée pas de véritable pointeur, mais est en fait un alias pour l'adresse du début de la chaîne, tandis que la seconde alloue réellement un pointeur désignant l'adresse de la chaîne.
Pas exactement. La syntaxe avec le crochet représente un tableau. C'est-à-dire la zone entière de la stack. En revanche, dans la plupart des contextes, il sera converti en adresse sur le 1er élément. Petit truc pour t'amuser :
sizeof p;
donnera un résultat différent selon ta définition de p (en tableau ou pointeur).
Note : oui, sizeof fait partie des quelques exceptions où le tableau n'est pas converti en pointeur.

As-tu une autre idée d'usage ?
Possibilité de réallouer dynamiquement la variable. Si par exemple, tu as besoin par la suite d'une autre taille, tu peux utiliser realloc().
Possibilité d'allouer une plus grande zone dans le heap que dans le stack.
Sécurisation : plus dur de corrompdre le stack que le heap, bien que les nouveaux compilateurs offrent des mécanismes de sécurité.
Etc.
0
Sugel Messages postés 4076 Date d'inscription   Statut Membre Dernière intervention   727
 
Attends, tu parles de l'usage de malloc ou de char *s="a"; ?

après vérification, les variables créées avec char *s=""; sont bien stockées dans la section
dédiée au code si leur longueur n'est pas trop importante, afin de justement profiter du statut de lecture seule de celle-ci, ou sont sinon déportée dans la section rdata, justement dédiée aux données en lecture seule.

La section data dispose elle d'un accès en écriture :
j'ai compilé un exécutable test et vérifié ça avec ollydbg.

du coup, l'usage de realloc n'est pas possible dans les deux cas, vu que dans les deux cas de figure l'agencement mémoire est invariable car défini par le compilateur.

Voilà tout !

Mp moi si tu veux des screens d'ollydbg ou le binaire de test

PS: dans mon message, je ne parlais pas de malloc en disant que je ne connaissait pas cette syntaxe, mais bien de char *s="a"; je ne suis quand même pas mauvais à ce point ;-)
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846 > Sugel Messages postés 4076 Date d'inscription   Statut Membre Dernière intervention  
 
Re,
Oui, oui, je parlais de :
char *p=malloc(...);


du coup, l'usage de realloc n'est pas possible dans les deux cas
Je parlais du malloc(). Bien sûr que ça ne marche pas si tu fais realloc(p, ...); dans le cas char *p="couocu". Néanmoins, tu peux quand même t'en sortir avec :
p=realloc(NULL, ...);
;-) Cela revient à faire un malloc().
0
Sugel Messages postés 4076 Date d'inscription   Statut Membre Dernière intervention   727
 
flute, j'ai failli me sentir intelligent :c
Tant pis, un jour peut-être :D

As-tu d'autres syntaxes merveilleusement obscures à me dévoiler, vénéré fiddy *-* ?
0