Titre: Pourquoi le programme fonctionne ? Posté par: Creaprog le 13 Décembre 2016 à 12:48:28 Bonjour,
Je rencontre un problème, une incompréhension en C. Code: int main(void) Le code fonctionne, mais je ne comprend pas. char *user permet de stocker l'adresse d'un char. Ensuite on essaye de mettre 4bytes dans l'adresse d'un char... Voici pour moi un code qui marche (oui c'est chelou une correction d'un code qui marche...) Code: int main(void) Cela fait 8 mois que je n'ai pas fait de C donc rester cool avec moi =) Je suis sur mon Mac et je n'ai pas de Linux actuellement sous la main, impossible de faire un valgrind :? Titre: Re : Pourquoi le programme fonctionne ? Posté par: Creaprog le 13 Décembre 2016 à 17:51:57 Merci pixis. Si je ne dit pas de connerie.
Dans le premier cas, on créer un pointeur de type char, ensuite il créer la chaine de caractère. Dans le deuxième cas, on sa créer direct la chaine de caractère. Titre: Re : Pourquoi le programme fonctionne ? Posté par: dionosis le 13 Décembre 2016 à 18:40:35 Salut,
En fait tes deux extraits de code sont strictement équivalents. :) Le type de la variable 'user' c'est (char*) et non pas (char). C'est probablement plus clair comme ça : Code: void foo() Donc tu vois bien que le faire sur une ligne ou sur deux revient au même. Quant au fait que tu puisses utiliser ce genre d'égalité, c'est simplement une facilité offerte par le compilateur. Ce qu'il se passe derrière c'est ça : Citation void foo() { static char _totoString[4+1] = "toto"; // 8 en réalité pour alignement, dans le tas (section datas initialisées du binaire loadé), donc scope local mais lifetime global, et initialisé au loadtime et non pas au runtime char *user; user = &_totoString[0]; puts(user); } Ca sera sûrement plus parlant comme ça. ;) ++ Ps: Je ne vois pas la réponse de pixis dont tu parles ?! Titre: Re : Pourquoi le programme fonctionne ? Posté par: the lsd le 13 Décembre 2016 à 19:34:06 La réponse de pixis était sur irc, j'ai dit que ça serait cool de l'écrire sur le forum une fois qu'ils auraient fini d'en parler, mais j'ai pas préciser comment l'écrire ^^'
Par contre, je suis d'accord avec dionosis, mais de ce que j'en ai compris sur irc, les deux codes n'étaient pas équivalent et l'un d'eux aurait pas du fonctionner (pas suivi tout l'affaire non plus) Enjoy The lsd Titre: Re : Pourquoi le programme fonctionne ? Posté par: dionosis le 13 Décembre 2016 à 21:07:02 Re,
Dac, ma réponse est correcte pour le code cité dans le post original, mais je vais tacher d'énumérer les autres différents cas de figure pour clarifier. Le code suivant (cas 1) : Code: char *user; équivaut à : Code: static char _totoString[4+1] = "toto"; // 8 en réalité pour alignement, dans un TAS (section datas INITIALISEES du binaire loadé), scope GLOBAL et lifetime GLOBAL, initialisé au LOADTIME Le code suivant (cas 2) : Code: char *user = "toto"; équivaut à : Code: static char user[4+1] = "toto"; // 8 en réalité pour alignement, dans un TAS (section datas INITIALISEES du binaire loadé), scope GLOBAL et lifetime GLOBAL, initialisé au LOADTIME Le code suivant (cas 3) : Code: void foo() équivaut à (Edit2: en 32 bits, si la version 64 bits vous intéresse faites le moi savoir) : Code: void foo() MAIS pourra si la chaîne est trop longue et selon l'optimisation être traduit vers justement le cas 0 de ma réponse initiale ! C'est ce cas qui est ambigü. Le code suivant (cas 4) : Code: char user[4+1]; et le code suivant (cas 5) : Code: void foo() sont incorrects. Il faudra employer une méthode/fonction de copie, ou bien le faire manuellement. Edit1: On m'a demandé de vérifier sous gcc, et donc en fait user[] : - sous visual se comporte comme le cas 0 de ma réponse initiale (*user, conforme) - sous gcc/mingw se comporte comme le cas 3 de cette réponse ci (user[n_auto], non conforme, et donc ambigu aussi) Arf, ça m'apprendra à vouloir répondre en 5 minutes quand c'est merdeux comme ça. :lol: ++ Titre: Re : Pourquoi le programme fonctionne ? Posté par: pixis le 13 Décembre 2016 à 23:49:43 Avec la première réponse, dionosis avait résumé grosso modo ce que j'avais raconté sur IRC :)
Titre: Re : Pourquoi le programme fonctionne ? Posté par: the lsd le 14 Décembre 2016 à 11:41:10 En tout cas, GG pour ta réponse de ouf dionosis ! :)
Enjoy The lsd Titre: Re : Pourquoi le programme fonctionne ? Posté par: Creaprog le 14 Décembre 2016 à 16:56:25 architecture low-endian == Endianness ?
Code: *pUser = 0x6F746F74; // dans le cas d'une architecture low-endian Titre: Re : Pourquoi le programme fonctionne ? Posté par: dionosis le 14 Décembre 2016 à 20:26:01 Salut,
Citation de: Creaprog Comment il a deviner l'adresse au pif ? - '*pUser' est la valeur pointée, 'pUser' est le pointeur. Go cours C sur les pointeurs (en fait je crois que c'est ça ton problème à la base).- "toto" en hexa c'est "\x74\x6F\x74\x6F" (+ "\x00" final). Inversé en low-endian. Go cours C sur les chaînes null terminated + cours d'architecture. ++ Titre: Re : Pourquoi le programme fonctionne ? Posté par: Creaprog le 14 Décembre 2016 à 21:49:01 Salut,
Merci de ton message j'ai relu encore et encore. Merci de m'avoir mit en pls. J'ai fais avant du C mais en bâclant, aujourd'hui je souhaite le reprendre avec des bases solides. Titre: Re : Pourquoi le programme fonctionne ? Posté par: dionosis le 15 Décembre 2016 à 02:03:21 Salut,
De rien ;) Bonne continuation. ++ |