mmmmh... Un brillant codeur pourrait-il m'expliquer ? [C] - C - Programmation
Marsh Posté le 15-01-2011 à 14:23:18
Mon explication, qui vaut ce qu'elle vaut
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
Marsh Posté le 15-01-2011 à 15:51:02
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+,
Marsh Posté le 15-01-2011 à 18:54:58
En général ça marche chez soi et ça pète le jour de la présentation
Marsh Posté le 15-01-2011 à 19:45:18
tequilatex a écrit : |
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 :
|
Marsh Posté le 16-01-2011 à 22:15:50
@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 !
Marsh Posté le 16-01-2011 à 23:11:20
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
Marsh Posté le 15-01-2011 à 13:48:14
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 !