Dans votre exemple, il myApple
a la valeur spéciale null
(généralement tous les bits nuls) et ne fait donc référence à rien. L'objet auquel il faisait référence à l'origine est maintenant perdu sur le tas. Il n'y a aucun moyen de récupérer son emplacement. Ceci est connu comme une fuite de mémoire sur les systèmes sans récupération de place.
Si vous définissez initialement 1 000 références sur null, vous ne disposez que de 1 000, généralement 1 000 * 4 octets (sur un système 32 bits, deux fois plus que sur 64). Si ces 1 000 références pointaient à l'origine sur des objets réels, vous avez alloué 1 000 fois la taille de chaque objet, plus un espace pour les 1 000 références.
Dans certaines langues (comme C et C ++), les pointeurs pointent toujours sur quelque chose, même "non initialisé". La question est de savoir si l'adresse qu'ils détiennent est légale pour votre programme. L'adresse spéciale zéro (alias null
) n'est délibérément pas mappée dans votre espace d'adressage, de sorte qu'une erreur de segmentation est générée par l'unité de gestion de la mémoire (MMU) lors de son accès et que votre programme se bloque. Mais puisque l'adresse zéro n'est délibérément pas mappée, elle devient une valeur idéale à utiliser pour indiquer qu'un pointeur ne pointe rien, d'où son rôle null
. Pour compléter l’histoire, lorsque vous allouez de la mémoire avec new
oumalloc()
, le système d’exploitation configure le MMU pour mapper les pages de RAM dans votre espace adresse et les rendre utilisables. Il existe encore généralement de vastes plages d'espace d'adressage non mappées, ce qui entraîne également des erreurs de segmentation.
std::shared_ptr<Apple>
est un exemple qui n'est ni GC, ni les fuitesApple
lorsqu'il est mis à zéro.shared_ptr
simplement un formulaire de base pour la collecte des ordures? GC n’exige pas qu’il y ait un "ramasse-miettes" séparé, seulement cette poubelle a lieu.La réponse dépend de la langue que vous utilisez.
C / C ++
En C et C ++, le mot clé était NULL, et ce qui était vraiment NULL était 0. Il a été décidé que "0x0000" ne serait jamais un pointeur valide sur un objet. Il s'agit donc de la valeur qui est assignée pour indiquer qu'il n'est pas un pointeur valide. Cependant, c'est complètement arbitraire. Si vous tentiez d'y accéder comme un pointeur, il se comporterait exactement comme un pointeur vers un objet qui n'existe plus en mémoire, ce qui provoquerait la génération d'une exception de pointeur non valide. Le pointeur lui-même occupe de la mémoire, mais pas plus qu'un objet entier. Par conséquent, si vous avez 1000 pointeurs nuls, cela équivaut à 1000 entiers. Si certains de ces pointeurs pointent sur des objets valides, l'utilisation de la mémoire équivaudrait à 1 000 entiers plus la mémoire contenue dans ces pointeurs valides. Rappelez-vous qu'en C ou C ++,n'implique pas que la mémoire a été libérée, vous devez donc explicitement supprimer cet objet à l'aide de dealloc (C) ou delete (C ++).
Java
Contrairement à C et C ++, en Java, null n’est qu’un mot-clé. Plutôt que de gérer null comme un pointeur sur un objet, il est géré en interne et traité comme un littéral. Cela éliminait la nécessité de lier des pointeurs sous forme de types entiers et permettait à Java d’abstraire totalement les pointeurs Cependant, même si Java le cache mieux, ce sont toujours des pointeurs, ce qui signifie que 1000 pointeurs nuls consomment toujours l'équivalent de 1000 entiers. Évidemment, quand ils pointent sur des objets, un peu comme C et C ++, la mémoire est consommée par ces objets jusqu'à ce qu'aucun autre pointeur ne les référence, mais contrairement à C et C ++, le ramasse-miettes ramasse dessus lors de son prochain passage et libère de la mémoire, sans exiger que vous deviez suivre quels objets sont libérés et quels objets ne le sont pas, dans la plupart des cas (sauf si vous avez des raisons de faire référence à des objets avec une faible faiblesse, par exemple).
la source
NULL
( pas un mot-clé, en passant) sont traités comme s'il s'agissait de bits nuls. Mais ils ne doivent pas être mises en œuvre en tant que telle, et en fait certaines implémentations obscures font utiliser les pointeurs nuls non nuls. Si j'écris,if (myptr == 0)
le compilateur fera ce qu'il faut, même si le pointeur null est représenté en interne par0xabcdef
.0
est une constante de pointeur nulle, mais cela ne signifie pas quemyptr == 0
vérifie si tous les bits demyptr
sont zéro.NULL
macro, mais plutôt de parler du «pointeur nul» et de mentionner explicitement que «le littéral-0 peut être implicitement converti en un pointeur nul».Un pointeur est simplement une variable qui est principalement de type entier. Il spécifie une adresse mémoire où l'objet réel est stocké.
La plupart des langues permettent d'accéder aux membres de l'objet via cette variable de pointeur:
Le compilateur sait comment accéder aux membres d’un
Apple
. Il "suit" le pointeur versmyApple
l'adresse de et récupère la valeur duappleInt
Si vous affectez le pointeur null à une variable de pointeur, vous faites en sorte que le pointeur ne pointe pas sur une adresse mémoire. (Ce qui rend l'accès des membres impossible.)
Pour chaque pointeur, vous avez besoin de mémoire pour contenir la valeur entière de l'adresse mémoire (généralement 4 octets sur des systèmes 32 bits, 8 octets sur des systèmes 64 bits). Ceci est également vrai pour les pointeurs nuls.
la source
Exemple rapide (les noms de variables ne sont pas enregistrés):
À votre santé.
la source