Codage
Partie de code traité en bleu
- Donnez l'adresse de la variable bonjour. Donnez son contenu complet. Donnez la taille de la variable. Y a t'il des cases non utilisées ? Peut-on lui affecter plus tard une autre adresse ?
char bonjour[10] ="bonjour";
bonjour est un tableau de caractères. Ce tableau dispose donc de 10 cases dont chacune représente un caractère. Finalement, la dimension du tableau est de 10 octets. La constante littérale chaîne "bonjour" est composée se 8 caractères (il ne faut pas oublier le caractère de fin de chaîne). Du coup, les deux dernières cases du tableau ne sont pas exploitées, et leur contenue est aléatoire. Comme toutes les variables déclarées au départ, leurs adresses sont figées une fois pour toute. Il est vrai qu'un tableau est considéré comme un pointeur, mais il s'agit d'un pointeur constant, donc même dans cette interprétation, il n'est pas possible de proposer une autre adresse.
- Donnez l'adresse de la variable salut. A quoi correspond son contenu ? Evaluer son contenu ? Son contenu peut-il varier ? Où se situe la chaîne « salut ». Déterminez son adresse. Quelle est sa taille ?
char *salut = "salut";
Cette fois-ci, il s'agit d'un pointeur de caractères. Donc, le contenu de cette variable est systématiquement une adresse et pour l'instant, cette adresse représente l'adresse de la constante littérale "salut". Finalement, la variable salut accède indirectement (pointe) au contenu de la constante littérale. Comme pour toutes les variable, à tout moment, il est possible de changer le contenu du pointeur, et donc de proposer une autre adresse. Les constantes littérales sont connues dès le départ. A ce sujet, elles sont généralement déclarées dans la zone statique. La dimension de cette constante littérale correspond exactement à la taille de la chaîne de caractères, ce qui la différencie du tableau où vous êtes souvent obligés de proposer une dimention beaucoup plus grande pour accepter les différentes chaînes.
- Donnez l'adresse de la variable message. Quelle est la valeur de son contenu ? Est-ce que cette valeur est cohérente ? A quoi correspond normalement ce type de valeur ?
char *message;
Il s'agit également d'un pointeur de caractères. Cette fois-ci, la variable n'est pas explicitement initialisée. Du coup, son contenu est aléatoire, mais correspond tout de même à une adresse. Sans initialisation ultérieure, notre variable pointera quelque part. Toutefois, comme cette adresse est quelconque, le pointeur peut indirectement se connecter au milieu d'une variable, où même sur une zone mémoire qui correspond au programme (zone de code). Dans ce dernier cas, il est possible de faire de l'auto-destruction.
- Donnez l'adresse de la variable bienvenue. A quoi correspond son contenu ? Evaluer son contenu ? Son contenu peut-il varier ? Ou se situe la chaîne représentée par char[10]. Déterminez son adresse. Quelle est sa taille ? Quelle est sa valeur ? Sa valeur est-elle cohérente ?
char *bienvenue = new char[10];
bienvenue est également un pointeur de caractères. Son contenu est donc une adresse et comme pour tous les pointeurs (et même pour toutes les autres variables) son contenu peut varier. Cette fois-ci, et à ce moment là, ce pointeur adresse une variable dynamique déclarée dans le tas (new). La zone allouée pour cette variable dynamique représente une chaîne de 10 caractères. A l'heure actuelle, le contenu de cette chaîne est totalement aléatoire.
Partie de code traité en rouge
- Que se passe t-il sur cette ligne ? Evaluer son contenu ? A quoi correspond son contenu ? Que devient la chaîne représentée par char[10]. Est-elle toujours accessible ? Est-ce que l'instruction new char[10] a un sens ? Qu'est-ce qu'il aurait fallu faire pour que cette expression ait un sens ? Avec l'écriture proposée, y a t-il perte de mémoire ?
bienvenue = "bienvenue";
Nous venons de voir que bienvenue est un pointeur de caractères et qu'il est possible de proposer une autre adresse. En proposant cette écriture, le but était certainement de remplir la variable dynamique à l'aide de la constante littérale chaîne "bienvenue". Mais, ce n'est pas du tout ce qui se passe, bienvenue est un pointeur, il ne récupère donc qu'une adresse, et cette adresse est l'adresse de la constante littérale qui se situe quelque part dans la zone statique. Vu que ce pointeur dispose maintenant d'une autre adresse, la variable dynamique n'est plus du tout accessible, puisque le pointeur ne connait plus son adresse, et comme par définition une variable dynamique est anonyme, elle est définitivement perdue. Nous avons donc réserver un emplacement mémoire pour rien. La solution aurait été de réaliser une copie case par case à l'aide d'une itérative.
- Que se passe t-il sur cette ligne ? Evaluer son contenu ? A quoi correspond son contenu ?
message = bonjour;
Lorsque nous faisons référence à bonjour sans autre annotation, il s'agit donc du tableau dans son entier, mais plus précisément de l'adresse de sa première case. Grâce à cette instruction, message pointe désormais sur le tableau bonjour.
- Que se passe t-il sur cette ligne ? Evaluer son contenu ? A quoi correspond son contenu ? Que devient la chaîne « salut ». Est-elle toujours accessible ?
salut = bonjour;
Souvenez-vous que salut est également un pointeur (son contenu est une adresse) qui pointe également sur le tableau bonjour. Du coup, la constante littérale chaîne "salut", n'est plus accessible puisque son adresse a été écrasée par l'adresse du tableau bonjour. Cette constante littérale chaîne est définitivement perdue et sa zone mémoire ne sert plus à rien.
- Quelle est la chaîne de caractères modifiée ?
message[0] = 'B';
message pointe actuellement sur le tableau bonjour, du coup la modification proposée atteint indirectement le tableau bonjour. Du coup, la première lettre du message est mise en majuscule.
- Quelle est la chaîne de caractères modifiée ?
salut[0] = 'b';
salut pointe également sur bonjour. Le résultat revient à remettre la première lettre en minuscule. Nous remarquons qu'actuellement nous avons trois variables qui agissent sur la même zone mémoire.
- Quelle est la chaîne qui est libérée ? Est-ce que la chaîne représentée par new char[10] a été libérée ?
delete[ ] bienvenue;
bienvenue ne pointe plus du tout sur la variable dynamique et pointe sur la zone statique représentant la chaîne de caractères "bienvenue". Du coup, la variable dynamique ne peut jamais être libérée et le fait de proposer la libération d'une zone statique peut déclancher une exception. Souvenez-vous que delete propose de libérer une zone mémoire dont l'adresse est donnée par le pointeur.