Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2974 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [C] mmmmh... Un brillant codeur pourrait-il m'expliquer ?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] mmmmh... Un brillant codeur pourrait-il m'expliquer ?

n°2049296
tequilatex
Viva Tequila
Posté le 15-01-2011 à 13:48:14  profilanswer
 


Bonjour à tous,  
 
Je suis de retour en programmation C après bien des années passées en Java. Je vais bientôt avoir à encadrer les travaux de plusieurs étudiants sur de la programmation C, donc je leur prépare un petit rappel sur les choses à faire et à ne pas faire. Je codais des petits bouts de code, quand je suis tombé sur ce petit cas particulier. Codez ceci dans un main vide :  
 
 int * ptr;
 *ptr = 12;
 printf("%d\n", *ptr);
 
Ce petit bout de code est un exemple de chose "à ne pas faire". Evidemment, ptr n'a pas été initialisé. Et pourtant, ça marche. 12 est écrit quelque part dans la mémoire. En revanche, et là c'est beaucoup plus bizarre, codez ceci :
 
 int i = 25;
 int * ptr;
 *ptr = 12;
 printf("%d\n", *ptr);
 
La variable i ne sert absolument à rien dans notre cas, convenons-en. Pourtant, à la compilation, ce petit programme plante. Alors même qu'il marchait avant, et qu'on a simplement ajouté une ligne inutile...
 
Je précise que j'utilise minGW (émulation GCC sous windows), archi 32 bits, mais je ne serais pas étonné que cela fasse la même chose sous un GCC Linux. Est-ce que quelqu'un aurait une idée pour expliquer ce "phénomène" ?
 
Merci d'avance !

mood
Publicité
Posté le 15-01-2011 à 13:48:14  profilanswer
 

n°2049302
WiiDS
20 titres en GC, 0 abandon, 0 DQ
Posté le 15-01-2011 à 14:23:18  profilanswer
 

Mon explication, qui vaut ce qu'elle vaut :o

 

Dans ton premier exemple, ça marche, bien content pour toi mais c'est clairement mal. Ton int doit être écrit quelque part dans la mémoire ou ça ne dérange pas ton système d'exploitation. Chez moi, ptr était à 7efde000.

 

En revanche, en mettant un int supplémentaire, tu décales l'emplacement de ton pointeur ptr en mémoire, et pas de chance cette fois ptr se retrouve sur une adresse bidon sur laquelle tu ne pourras pas écrire (Chez moi ptr était à 0xf ...)

 

Je pense pas que l'explication aille beaucoup plus loin que ça. En se renseignant sur le fonctionnement de la gestion d'un mémoire par un programme tu auras peut être une explication plus concrète (Par exemple je me demande si une adresse 7efde000 ne correspond pas à une adresse proche de la pile, enfin bref) mais tout ce que tu dois expliquer à tes étudiants, c'est que utiliser un pointeur non initialisé, c'est le mal absolu et irréfutable :D


Message édité par WiiDS le 15-01-2011 à 14:25:08

---------------
"I can cry like Roger. It's just a shame I can't play like him" - Andy Murray, 2010
n°2049313
gilou
Modérateur
Modzilla
Posté le 15-01-2011 à 15:51:02  profilanswer
 

Citation :

Et pourtant, ça marche.

Par hasard.  
Avec un autre compilo, sur un autre OS, ça pourrait tout aussi bien planter.
 

Citation :

mais je ne serais pas étonné que cela fasse la même chose sous un GCC Linux

Peut être ou peut être pas. Et peut être que ça marchera tous les jours, sauf les mardis des années bissextiles. Bref, c'est un comportement indéfini, sur lequel il ne faut pas compter.
 
A+,
 


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2049349
Trap D
Posté le 15-01-2011 à 18:54:58  profilanswer
 

En général ça marche chez soi et ça pète le jour de la présentation


Message édité par Trap D le 15-01-2011 à 18:55:30
n°2049361
xilebo
noone
Posté le 15-01-2011 à 19:45:18  profilanswer
 

tequilatex a écrit :


Bonjour à tous,  
 
Je suis de retour en programmation C après bien des années passées en Java. Je vais bientôt avoir à encadrer les travaux de plusieurs étudiants sur de la programmation C, donc je leur prépare un petit rappel sur les choses à faire et à ne pas faire. Je codais des petits bouts de code, quand je suis tombé sur ce petit cas particulier. Codez ceci dans un main vide :  
 
 int * ptr;
 *ptr = 12;
 printf("%d\n", *ptr);
 
Ce petit bout de code est un exemple de chose "à ne pas faire". Evidemment, ptr n'a pas été initialisé. Et pourtant, ça marche. 12 est écrit quelque part dans la mémoire. En revanche, et là c'est beaucoup plus bizarre, codez ceci :
 
 int i = 25;
 int * ptr;
 *ptr = 12;
 printf("%d\n", *ptr);
 
La variable i ne sert absolument à rien dans notre cas, convenons-en. Pourtant, à la compilation, ce petit programme plante. Alors même qu'il marchait avant, et qu'on a simplement ajouté une ligne inutile...
 
Je précise que j'utilise minGW (émulation GCC sous windows), archi 32 bits, mais je ne serais pas étonné que cela fasse la même chose sous un GCC Linux. Est-ce que quelqu'un aurait une idée pour expliquer ce "phénomène" ?
 
Merci d'avance !


 
Cela m'étonnerait que ton programme plante à la compilation. C'est plutôt à l'exécution qu'il plante.
 
Généralement ça "plante" dès qu'on tente d'écrire à une adresse non autorisée. C'est le système d'exploitation qui gère cela ( déclenche SIGSEGV sous linux par exemple ), car en réalité, le fait d'écraser une valeur mémoire n'a aucune incidence au moment où on le fait ( sous-entendu, cela ne déclenche pas un plantage au moment de l'écriture, mais plutôt à la prochaine utilisation de la valeur contenue à l'emplacement écrasé ).  
 
 
Dans ton 2eme exemple, il te suffit de faire cela pour que le code soit valide :
 

Code :
  1. int i = 25;
  2. int * ptr = &i;
  3. *ptr = 12;
  4. printf("%d\n", *ptr);

n°2049517
tequilatex
Viva Tequila
Posté le 16-01-2011 à 22:15:50  profilanswer
 

@xilebo oui, ça plante à l'exécution et non à la compilation dsl. Je voyais très bien quoi faire pour que ça marche, c'était juste cette petite "exception" pour laquelle je me demandais s'il y avait une réponse rationnelle ou non.
 
Donc c'est sans doute bien une question de pointage mémoire qui va s'initialiser à un endroit qui peut ou non autoriser l'écriture, au petit bonheur la chance. ^^ Merci pour vos participations !

n°2049551
gzii
court-circuit
Posté le 16-01-2011 à 23:11:20  profilanswer
 

Oui très bien pour faire de l'aléatoire, voire même planter le debugger comme ça m'était arrivé une fois il y a fort longtemps (windows NT 4.0 je crois et microsoft visual c++), et m'avait valu plusieurs heures à m'arracher les cheveux à cause d'erreurs incompréhensibles :lol:


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [C] mmmmh... Un brillant codeur pourrait-il m'expliquer ?

 

Sujets relatifs
[MATLAB] compiler un réseau de neuronne en C++[C++] Traitement d'image par pixel (bits)
FILE et Structure en C++[C++] Date limite d'utilisation d'un logiciel
[C] SurchargeVIsual Studio C# 2008 - option Type de la plateforme cible
Erreur de compilation C++Gestion d'évenement en C#
[C++] tableau de classe dans une autre classe ?Langage C : Exercice sur les files
Plus de sujets relatifs à : [C] mmmmh... Un brillant codeur pourrait-il m'expliquer ?


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR