Suppression d'un pointeur en C++

contexte: j'essaie d'enrouler ma tête autour de pointeurs, nous les avons vus il y a quelques semaines à l'école et en m'entraînant aujourd'hui, j'ai rencontré un idiot? problème, ça peut être très simple pour vous, mais j'ai peu ou pas d'expérience en programmation.

j'ai vu pas mal de questions dans SO à propos de la suppression des pointeurs mais ils semblent tous être liés à la suppression d'une classe et pas un pointeur "simple" (ou quel que soit le terme approprié pourrait être), voici le code je suis essayer de courir:

#include <iostream>;

using namespace std;

int main() {
  int myVar,
      *myPointer;

  myVar = 8;
  myPointer = &myVar;

  cout << "delete-ing pointers " << endl;
  cout << "Memory address: " << myPointer << endl;

  // Seems I can't *just* delete it, as it triggers an error 
  delete myPointer;
  cout << "myPointer: " << myPointer << endl;
  // Error: a.out(14399) malloc: *** error for object 0x7fff61e537f4:
  // pointer being freed was not allocated
  // *** set a breakpoint in malloc_error_break to debug
  // Abort trap: 6

  // Using the new keyword befor deleting it works, but
  // does it really frees up the space? 
  myPointer = new int;
  delete myPointer;
  cout << "myPointer: " << myPointer << endl;
  // myPointer continues to store a memory address.

  // Using NULL before deleting it, seems to work. 
  myPointer = NULL;
  delete myPointer;
  cout << "myPointer: " << myPointer << endl;
  // myPointer returns 0.

}

donc mes questions sont:

  1. Pourquoi n'est-il pas le premier cas de travail? Semble l'utilisation la plus simple pour utiliser et supprimer un pointeur? L'erreur indique que la mémoire n'a pas été attribuée mais 'cout' a renvoyé une adresse.
  2. dans le deuxième exemple, l'erreur n'est pas déclenchée, mais faire un sort de la valeur de mapointer still renvoie une adresse mémoire?
  3. Est-ce que #3 fonctionne vraiment? Semble fonctionner pour moi, le pointeur n'est plus à stocker une adresse, est-ce la bonne façon de supprimer un pointeur?

Désolé pour la longue question, a voulu faire de ce aussi clair que possible, de répéter, j'ai peu d'expérience en programmation, donc si quelqu'un pouvait répondre à cette aide de termes simples, il serait grandement apprécié!

59
demandé sur Brian Tompsett - 汤莱恩 2012-11-05 02:02:31

6 réponses

1 & 2

myVar = 8; //not dynamically allocated. Can't call delete on it.
myPointer = new int; //dynamically allocated, can call delete on it.

la première variable a été attribuée sur la pile. Vous pouvez appeler supprimer uniquement sur la mémoire que vous avez affectée dynamiquement (sur le tas) en utilisant l'opérateur new .

3.

  myPointer = NULL;
  delete myPointer;

ci-dessus n' rien du tout . Vous n'avez rien libéré, comme le pointeur pointait à NULL.


ce qui suit ne devrait pas être fait:

myPointer = new int;
myPointer = NULL; //leaked memory, no pointer to above int
delete myPointer; //no point at all

vous l'avez pointé à NULL, laissant derrière vous une fuite de mémoire (le nouveau int que vous avez alloué). Vous devriez libérer le souvenir que vous pointez. Il n'y a plus aucun moyen d'accéder à celui alloué new int , d'où une fuite de mémoire.


la bonne façon:

myPointer = new int;
delete myPointer; //freed memory
myPointer = NULL; //pointed dangling ptr to NULL

La meilleure façon:

si vous utilisez C++, ne pas utilisez des pointeurs crus. Utilisez pointeurs intelligents à la place qui peut gérer ces choses pour vous avec peu au-dessus. C++11 est livré avec plusieurs .

121
répondu Anirudh Ramanathan 2017-05-23 10:31:17

je crois que vous ne comprenez pas tout à fait comment les pointeurs fonctionnent.

Quand vous avez un pointeur pointant vers une certaine mémoire il y a trois choses différentes que vous devez comprendre:

- il y a "ce qui est pointé" par le pointeur (la mémoire)

- cette adresse mémoire

- tous les pointeurs n'ont pas besoin de supprimer leur mémoire: il suffit de supprimer la mémoire qui a été affectée dynamiquement (utilisé new opérateur.)

Imaginez:

int *ptr = new int; 
// ptr has the address of the memory.
// at this point, the actual memory doesn't have anything.
*ptr = 8;
// you're assigning the integer 8 into that memory.
delete ptr;
// you are only deleting the memory.
// at this point the pointer still has the same memory address (as you could
//   notice from your 2nd test) but what inside that memory is gone!

Quand vous avez fait

ptr = NULL;
// you didn't delete the memory
// you're only saying that this pointer is now pointing to "nowhere".
// the memory that was pointed by this pointer is now lost.

C++ permet que vous essayiez de delete un pointeur qui pointe vers null mais il ne fait rien, il ne donne juste aucune erreur.

14
répondu salgadokk 2012-11-05 00:00:39
Les pointeurs

sont similaires aux variables normales en ce que vous n'avez pas besoin de les supprimer. Ils sont supprimées de la mémoire à la fin d'une des fonctions d'exécution et/ou la fin du programme.

vous pouvez cependant utiliser des pointeurs pour allouer un 'bloc' de mémoire, par exemple comme ceci:

int *some_integers = new int[20000]

cette attribuera l'espace de mémoire pour 20000 entiers. Utile, parce que la Pile a une taille limitée, et vous pourriez perdre sur avec une grosse charge de 'entiers' sans une erreur de dépassement de pile.

chaque fois que vous appelez new, Vous devriez alors 'delete' à la fin de votre programme, parce que sinon vous obtiendrez une fuite de mémoire, et de l'espace mémoire alloué ne sera jamais retourné pour d'autres programmes à utiliser. Pour ce faire:

delete [] some_integers;

Espère que ça aide.

10
répondu user3728501 2012-11-12 18:59:01

il y a une règle en C++, pour chaque nouveau il y a un supprimer .

  1. Pourquoi n'est-il pas le premier cas de travail? Semble l'utilisation la plus simple pour utiliser et supprimer un pointeur? L'erreur indique que la mémoire n'a pas été attribuée mais 'cout' a renvoyé une adresse.

nouveau n'est jamais appelé. Donc l'adresse que cout imprime est adresse de l'emplacement mémoire de myVar, ou la valeur attribuée à myPointer dans ce cas. Par écrit:

myPointer = &myVar;

vous dites:

myPointer = l'adresse où les données de myVar sont stockées

  1. sur le second exemple, l'erreur n'est pas déclenchée mais faire un sort de la valeur de myPointer renvoie quand même une adresse mémoire?

renvoie une adresse qui pointe vers un emplacement mémoire qui a été supprimé. Parce que d'abord vous créez le pointeur et assignez sa valeur à myPointer, ensuite vous le supprimez, enfin vous l'Imprimez. Donc, à moins que vous assigniez une autre valeur à myPointer, l'adresse supprimée restera.

  1. N' #3 fonctionnent vraiment? Semble fonctionner pour moi, le pointeur n'est plus à stocker une adresse, est-ce la bonne façon de supprimer un pointeur?

NULL égale 0, vous supprimez 0, donc vous ne supprimez rien. Et c'est logique qu'il imprime 0 parce que vous avez fait:

myPointer = NULL;

qui est égal à:

myPointer = 0;
7
répondu fonZ 2016-01-17 20:06:49
  1. vous essayez de supprimer une variable attribuée sur la pile. Vous ne pouvez pas faire cela
  2. supprimer un pointeur ne détruit pas un pointeur en fait, seule la mémoire occupée est rendue à L'OS. Vous pouvez y accéder jusqu'à ce que la mémoire soit utilisée pour une autre variable, ou manipulée. C'est donc une bonne pratique de définir un pointeur à NULL (0) après la suppression.
  3. supprimer un pointeur nul ne supprime rien.
4
répondu Hakan Serce 2012-11-04 22:11:40
int value, *ptr;

value = 8;
ptr = &value;
// ptr points to value, which lives on a stack frame.
// you are not responsible for managing its lifetime.

ptr = new int;
delete ptr;
// yes this is the normal way to manage the lifetime of
// dynamically allocated memory, you new'ed it, you delete it.

ptr = nullptr;
delete ptr;
// this is illogical, essentially you are saying delete nothing.
1
répondu Casper Beyer 2012-11-04 22:15:46