-6
votes

Pourquoi un pointeur utilise-t-il plus de mémoire qu'une variable?

Je pensais que les pointeurs étaient censés aider un programme plus efficace de mémoire. Je ne comprends pas pourquoi le pointeur "X" prend plus d'espace que la variable "Y". J'exécute ce programme sur un ordinateur Windows 64 bits. Jetez un coup d'œil à ce programme simple.

#include <iostream>
using namespace std;

int main() {

    // Creating new int
    int *X = new int; *X = 2000000000;
    cout << sizeof(X) << ", " << sizeof(*X) << endl;

    // Deleting the new int
    delete x;
    cout << sizeof(X) << ", " << sizeof(*X) << endl;

    // Using a simple variable
    int Y = 2000000000;
    cout << sizeof(Y);
}


9 commentaires

Où avez-vous appris que le pointeur doit aider à sauver la mémoire? On dirait que vous pouvez utiliser un Good C ++ Book


"Je pensais que les pointeurs étaient censés aider un programme plus efficace de mémoire." - Vous avez cru mal, les pointeurs n'ont rien à voir avec "l'efficacité de la mémoire".


Pourquoi croyez-vous que les pointeurs aident à l'empreinte de la mémoire d'un programme? Leur objectif est de pointer des choses, c'est tout. Sur un système 64 bits, cela en fait 8 octets pour pouvoir couvrir tout l'espace d'adressage.


"Pourquoi un pointeur utilise-t-il plus de mémoire qu'une variable?" - Un pointeur est une variable. C'est une variable contenant une adresse de quelque chose d'autre (c'est pointant vers autre autre).


Je ne suis pas sûr d'où cela vient de, des pointeurs (et des références) peut en effet aider à économiser beaucoup de mémoire lorsqu'il est utilisé pour passer de gros trucs autour au lieu de passer ce type de valeur.


" Je pensais que les pointeurs étaient censés aider un programme plus efficace de mémoire. " Comment? Lorsque vous utilisez int y; , votre programme doit attribuer uniquement la mémoire uniquement pour int . Lorsque vous utilisez int * x = nouveau int; , votre programme doit allouer la mémoire pour int , et pour int * < / code>, pour faire référence à ladite int . Donc, je ne vois pas comment "utiliser des pointeurs peut aider à être plus efficace".


Je soupçonne que vous lisez ou entendiez que les pointeurs aident à la gestion de la mémoire . C'est vrai, mais ils n'assistent pas généralement en utilisant moins de mémoire .


Par rapport à la valeur pass par rapport, un paramètre formel passé par-cons-ref (ou Const-pointeur) évite la création d'une copie. Lorsque le paramètre formel est «grand», cela évite à la fois du temps et de l'espace. Oui, un pointeur peut enregistrer (automatique) mémoire!


Imaginez votre «Principal ()» créé et rempli un objet de mémoire dynamique, «Bigobj * Bodata», qui occupait plus de la moitié de votre mémoire dynamique système. Même "bodata", passée par la référence constante (c'est-à-dire FOO (* bodata)), permettra de gagner du temps et de suffisamment de mémoire dynamique pour éviter le débordement de la mémoire (et / ou peut-être une partition de swap).


3 Réponses :


-2
votes

Strictement parlant, un pointeur est une variable qui doit stocker une adresse. Le pointeur a besoin d'une longueur appropriée pour stocker l'adresse en question. Une adresse a une longueur qui est nécessaire pour s'adapter. Mais une variable peut également avoir une longueur différente selon le type, y compris les pointeurs . En d'autres termes, lorsque chaque type a une plage spécifique de valeurs, il doit contenir un pointeur doit pouvoir contenir l'adresse.

Un exemple où le passage d'un pointeur enregistre l'espace est dans la mémoire contiguë (c'est-à-dire une matrice primitive). Si vous savez que vous avez 100 entiers les uns des autres, il vous suffit de passer l'adresse à la première.


6 commentaires

Les pointeurs peuvent également avoir des tailles différentes. Par exemple, des pointeurs vers des membres contre des pointeurs vers des non-membres. Et historiquement, différents pointeurs de tailles utilisées avec différents modèles de mémoire.


Même char * et int * peut avoir des tailles différentes.


Comment est-ce une réponse à la question?


@ Sergeya, j'ai mis à jour ma réponse pour essayer d'être plus clair. Si vous pensez que vous pouvez l'améliorer, vous êtes libre de le modifier :)


@Daniel vous êtes au courant du tableau en décomposition, n'est-ce pas?


@ πάνταῥεῖ, oui un tableau décrit dans un pointeur lorsqu'il est passé pour cette raison. Étiez-vous à pousser chaque élément du tableau sur la pile que ce serait moins efficace.



1
votes

Quelqu'un peut-il donner un exemple de la manière dont un pointeur a réellement aidé à sauver la mémoire?

Cela n'a pas permis de sauvegarder votre mémoire du tout. Il n'y a aucune raison de supposer qu'il aurait dû sauver la mémoire.

Pourquoi un pointeur utilise-t-il plus de mémoire qu'une variable?

Une variable utilise (au moins) autant de mémoire que son type nécessite. La taille d'un type dépend du nombre d'états différents qu'il a besoin pour pouvoir représenter.

Par exemple, la taille de int doit comporter au moins 16 bits afin de représenter tous les entiers qu'il est tenu de représenter en fonction des règles de langue. Un pointeur d'autre part doit être suffisamment grand pour pouvoir pointer n'importe quel objet du type correspondant dans n'importe quelle adresse mémoire (dans laquelle un tel objet pourrait être localisé). Sur un système moderne typique, les pointeurs de données ont généralement la même taille que la taille de mot du processeur.

En conclusion: une variable de pointeur peut être supérieure à une variable non-pointeur, car différents types ont des besoins de mémoire différents, et certains types n'ont pas besoin de représenter autant d'états différents en tant que pointeur pourraient avoir besoin de représenter. Votre exemple démontre que int est un tel type sur votre système.


1 commentaires

Voir également le paramètre formel VS Paramètre actuel et Pass-By-Const-Pointer, Pass-By-Const-Ref, VS Pass-By-Value.



1
votes

L'exemple trivial d'une situation typique où les pointeurs peuvent aider à sauver la mémoire entraînerait des trucs. Une certaine fonction peut avoir besoin d'accéder à un objet important. Dans ce cas, l'objet de passage lui-même créera une copie de cet objet double quantité de mémoire utilisée par le premier objet.

  void foo(Large * p_large) {}

  int main()
  {
        Large large{}; // allocates at least sizeof(Large) bytes ~ 1000 bytes 
        foo(&large); // allocates at least sizeof(Large *) bytes ~ typically 4 or 8 bytes
  }


0 commentaires