Aller au contenu

[Résolu]Une n-ième question sur les pointeurs


Messages recommandés

Bonjour, soit le code suivant (je m'excuse pour les system("pause"), amis linuxiens :francais: ):

#include <iostream>

using namespace std;

int main(){
int* ptr = new int;

*ptr = 6;
cout << ptr << "|" << *ptr << "\n";
system("PAUSE");

delete ptr;
cout << ptr << "|" << *ptr << "\n";
system("PAUSE");

*ptr = 12;
cout << ptr << "|" << *ptr << "\n";
system("PAUSE");

return 0;
}

Qui donne en sortie :

0x3e2488|6
Press any key to continue . . .
0x3e2488|0
Press any key to continue . . .
0x3e2488|12
Press any key to continue . . .

Ce qui me dérange un peu, c'est ce qu'affiche le troisième cout. Bien que ptr pointe toujours sur le même emplacement mémoire, pourquoi a-t-il la capacité de modifier son contenu, étant donné qu'il a été désaloué par l'opérateur delete ?

Merci d'avance pour vos réponses

Lien vers le commentaire
Partager sur d’autres sites

Tu viens de faire (exprès) un gros bug. Tu as de la chance que ton programme ne fasse pas une faute générale de protection (écriture ou lecture d'une zone mémoire n'appartenant pas au programme).

Une fois que tu as libéré la mémoire, rien ne te garanti son contenu. Tu ne devrais même pas la lire et encore moins l'écrire, car elle n'appartient peut etre meme plus au programme....

La tu as écris 4 octets en mémoire. tu peux avoir ecrasé une variable, le voisin...

Il se trouve que comme ton programme est simple, tu n'a qu'une variable, que la mémoire n'est pas forcement libéré des que tu fais le delete.... Le gestionnaire de mémoire peut marquer le bloc libre mais le garder. J'ai un site qui explique ca mais je l'ai au boulot... je te le ferais passer.

Une adresse est une zone mémoire. Tu as "le droit" d'y lire/écrire tant qu'elle fais partie de l'espace d'adressage de ton programme. Ca ne fera pas de faute générale de protection tant que tu lis l'espace de ton programme.

Par contre, tu as bien compris qu'il ne fallait pas faire ca. Pour te prouver que c'est mal, quand tu fais un delete, tu devrais mettre ton pointeur a NULL. La je te garanti que si tu t'en sert, ca va péter car tu lira/ecrira une adresse en dehors de ton programme.

Lien vers le commentaire
Partager sur d’autres sites

Tu as "le droit" d'y lire/écrire tant qu'elle fais partie de l'espace d'adressage de ton programme. Ca ne fera pas de faute générale de protection tant que tu lis l'espace de ton programme.

C'est exactement ce que je voulais savoir. Merci pour ton explication claire et précise :transpi:

Lien vers le commentaire
Partager sur d’autres sites

Sur les systèmes actuels, la segmentation n'est plus lancée, le seul système de mémoire virtuelle qui subsiste, c'est la pagination qui consiste à découper l'espace en page et à attribuer au programme un certain nombre de page.

Quand ton programme réclame de la mémoire, l'OS lui attribue une nouvelle page (si tu ne connais le mécanisme de pagination, je te laisse regarder ceci), l'adresse de la page est stockée dans une table et les adresses de tes poiteurs sont stockés sous la forme d'un numéro de page et d'un décalage dans la page.

Alors, quand tu libères un pointeur, la page n'est pas nécéssairement supprimée de la table. Et du coup, quand tu accède au pointeur, l'OS trouve bien la page correspondante dans la table et te dit que tu as le droit de lire/d'écrire dedans.

Mais attention, c'est un comprtement non garanti : l'OS peut se réserver le droit de supprimmer la page.

Ce que je trouve plus étonnant, c'est que la valeur soit mise à zéro après le delete.

Tiens, un petit test amusant :

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
	int * p;
	int * start_p;
	p = malloc(1*sizeof(int));

	start_p = p;
	while(1)
	{
			printf("%d | %u : %d\n", p, *p, (p-start_p));
			p++;
	}

	return 0;
}

On peux aller bien loin dans une seule page :arrow:

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...