Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Code zarbi

9 réponses
Avatar
Aldo
Bonjour

Dans un programme C j'ai un code du stlye :


char pointeur[10]="chaine";

Ca compile sans warning, mais je trouve ca délirant d'allouer un
tableau pour ensuite faire pointer le pointeur sous-jacent vers une
zone statique...

Ca va planter si on ecrit dans *pointeur, non ? surtout si on depasse
les n caractères de la chaine statique ?

Merci

9 réponses

Avatar
Xavier Roche
Dans un programme C j'ai un code du stlye :
char pointeur[10]="chaine";


C'est un tableau initialisé, c'est assez standard, strictement équivalent à:
char pointeur[10] = { 'c', 'h', 'a', 'i', 'n', 'e', 0, 0, 0, 0 };

Attention donc aux 'char foo[1024] = "bar"' qui contiennent un memset()
caché à l'interieur (performances..)

Avatar
Pierre Maurette
Bonjour

Dans un programme C j'ai un code du stlye :


char pointeur[10]="chaine";

Ca compile sans warning, mais je trouve ca délirant d'allouer un tableau pour
ensuite faire pointer le pointeur sous-jacent vers une zone statique...


Le seul truc délirant, c'est le nommage. On ne déclare (et on
initialise) en aucun cas un pointeur, mais un tableau de 10 char.

Ca va planter si on ecrit dans *pointeur, non ?


Non. pointeur[10] est un tableau de char, automatique local. Il est
initialisé par {'c', 'h', 'a', 'i', 'n', 'e', ''}. Je vous laisse
vérifier, mais il me semble (j'en suis pratiquement certain) qu'il est
complété par des ''.

surtout si on depasse les n
caractères de la chaine statique ?


Là, oui. Et même plus grave, ça peut ne pas planter ;-)

Merci


De rien.

--
Pierre Maurette

Avatar
Eric Levenez
Le 5/11/06 14:20, dans , « Aldo »
a écrit :

Dans un programme C j'ai un code du stlye :


char pointeur[10]="chaine";

Ca compile sans warning,


Normal.

mais je trouve ca délirant d'allouer un
tableau pour ensuite faire pointer le pointeur sous-jacent vers une
zone statique...


"pointeur sous-jacent" ?

"pointeur" n'est pas un pointeur (contrairement à ce que son nom indique)
mais un tableau de 10 char que l'on initialise avec "chaine" (et des 0 en
fin). C'est tout à fait propre.

Une déclaration du genre :

char *pointeur = "chaine";

définit un véritable pointeur initialisé par l'adresse d'une chaîne
constante de 7 char (avec le 0 final).

La différence entre les 2 est que dans le premier cas (ton code), on peut
modifier les char du tableau, alors que dans le second cas on ne peut pas.

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.

Avatar
Harpo
Aldo wrote:

Bonjour

Dans un programme C j'ai un code du stlye :


char pointeur[10]="chaine";

Ca compile sans warning, mais je trouve ca délirant d'allouer un
tableau pour ensuite faire pointer le pointeur sous-jacent vers une
zone statique...


C'est pas comme ça que ça marche.
En gros, il y a 10 char alloués pour la variable automatique (e.g. dans
la pile) si c'est à l'intérieur d'une fonction.
Il n'y a pas allocation d'un pointeur, mais la référence à la chaîne est
résolue à la compilation et 'pointeur' peut être utilisé comme s'il
s'agissait d'un pointeur, enfin presque, je ne conseillerais pas de
l'incrémenter.

Le code 'délirant' est en fait un code tout à fait normal et classique
si on veut avoir une chaîne modifiable à l'intérieur d'une fonction.

Ca va planter si on ecrit dans *pointeur, non ?


Non.

surtout si on depasse les n caractères de la chaine statique ?


Pas nécessairement, malheureusement. Mais plus on dépasse plus on a de
chances, enfin il ne faut pas trop compter là-dessus.

Ca aurait plus vraisemblablement planté (mais je ne suis pas sûr *du
char * pointeur = "chaine";
Là le nom 'pointeur' aurait été plus justifié car la variable pointeur
est un pointeur. les caractères "chaine" auraient été alloués quelque
part ailleurs que dans la pile et pointeur renseigné avec leur adresse.
Pour avoir plus de chance de planter :
const char * pointeur = "chaine";
Car la chaine peut être allouée dans une page protégée en écriture.

--
http://patrick.davalan.free.fr/

Avatar
Xavier Roche
Il n'y a pas allocation d'un pointeur, mais la référence à la chaîne est
résolue à la compilation et 'pointeur' peut être utilisé comme s'il


'pointeur' n'est pas un pointeur, mais un tableau, sur lequel aucune
opération arithmétique ne peut être effectuée (pointeur++ n'a aucun sens
et provoquera une erreur de compilation)

Pas nécessairement, malheureusement. Mais plus on dépasse plus on a de
chances, enfin il ne faut pas trop compter là-dessus.


Cela corromp en général la pile, avec des résultats rigolos (code qui
plante plusieurs milliers de lignes plus loin sans raison apparente -
des heures de fun en perspectve avec votre débugger)

char * pointeur = "chaine";


Les chaines sont constantes il me semble dans la norme, et 'char *foo =
"bar"' est un archaïsme assez génant car il peut amener des bugs.
(l'option '-Wwrite-strings' de gcc est à conseiller amha pour cette raison)

les caractères "chaine" auraient été alloués quelque
part ailleurs que dans la pile et pointeur renseigné avec leur adresse.


Dans une (la) zone read-only en général (qui pourra être partagée si le
module est chargé par plusieurs processus)

Pour avoir plus de chance de planter :
const char * pointeur = "chaine";


Mais là le compilateur sympa vous préviendra que l'écriture n'est pas
possible.

Avatar
Jean-Marc Bourguet
Harpo writes:

'pointeur' peut être utilisé comme s'il s'agissait d'un pointeur, enfin
presque, je ne conseillerais pas de l'incrémenter.


pointeur est une variable de type tableau. Les valeurs de type tableaux
(que ce soient des variables ou non) sont converties implicitement en un
pointeur vers leur premier élément dans quasiment tous les contextes
(exceptions: en tant qu'argument de sizeof et en tant qu'argument de &; il
me semble mais je ne suis pas sûr qu'il n'y a pas d'autres exceptions en C;
les règles du C font qu'il n'y a pas de rvalue de type tableau).

A+

--
Jean-Marc
FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Harpo
Xavier Roche wrote:

Il n'y a pas allocation d'un pointeur, mais la référence à la chaîne
est résolue à la compilation et 'pointeur' peut être utilisé comme
s'il


'pointeur' n'est pas un pointeur, mais un tableau, sur lequel aucune
opération arithmétique ne peut être effectuée (pointeur++ n'a aucun
sens et provoquera une erreur de compilation)


C'est ce que je laissais entendre plus loin, en fait je ne sais même pas
si ça provoque une erreur de compile, je n'ai jamais essayé.

Pour avoir plus de chance de planter :
const char * pointeur = "chaine";


Mais là le compilateur sympa vous préviendra que l'écriture n'est pas
possible.


Je ne sais pas. C'est possible, il faudrait qu'il sache que ce pointeur
ait gardé sa valeur d'initialisation.

--
http://patrick.davalan.free.fr/


Avatar
Xavier Roche
Je ne sais pas. C'est possible, il faudrait qu'il sache que ce pointeur
ait gardé sa valeur d'initialisation.


Non, c'est le "const" qui est explicite pour le compilateur.

Avatar
Harpo
Xavier Roche wrote:

Je ne sais pas. C'est possible, il faudrait qu'il sache que ce
pointeur ait gardé sa valeur d'initialisation.


Non, c'est le "const" qui est explicite pour le compilateur.


Heu oui...

--
http://patrick.davalan.free.fr/