que - Eliminar un puntero en C++
punteros c++ (6)
Hay una regla en C ++, por cada nuevo hay una eliminación .
- ¿Por qué no funcionará el primer caso? Parece el uso más directo para usar y eliminar un puntero? El error dice que la memoria no fue asignada pero ''cout'' devolvió una dirección.
nuevo nunca se llama. Entonces, la dirección que se imprime es la dirección de la ubicación de memoria de myVar, o el valor asignado a myPointer en este caso. Al escribir:
myPointer = &myVar;
tu dices:
myPointer = La dirección de donde se almacenan los datos en myVar
- En el segundo ejemplo, el error no se desencadena, pero al hacer una llamada del valor de myPointer, ¿aún devuelve una dirección de memoria?
Devuelve una dirección que apunta a una ubicación de memoria que se ha eliminado. Porque primero creas el puntero y le asignas su valor a myPointer, luego lo borras y en tercer lugar lo imprimes. A menos que asigne otro valor a myPointer, la dirección eliminada permanecerá.
- ¿El # 3 realmente funciona? Parece que me funciona, el puntero ya no almacena una dirección, ¿es esta la manera correcta de borrar un puntero?
NULL equivale a 0, elimina 0, por lo que no elimina nada. Y es lógico que imprima 0 porque lo hiciste:
myPointer = NULL;
que es igual a:
myPointer = 0;
Contexto: estoy tratando de guiarme por los punteros, acabamos de verlos hace un par de semanas en la escuela y mientras practicaba hoy me encontré con un tonto? problema, puede ser muy sencillo para usted, pero tengo poca o ninguna experiencia en programación.
He visto bastantes preguntas en SO sobre la eliminación de punteros, pero todas parecen estar relacionadas con la eliminación de una clase y no un puntero ''simple'' (o cualquiera que sea el término correcto), aquí está el código que estoy tratando de correr:
#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.
}
Entonces mis preguntas son:
- ¿Por qué no funcionará el primer caso? Parece el uso más directo para usar y eliminar un puntero? El error dice que la memoria no fue asignada pero ''cout'' devolvió una dirección.
- En el segundo ejemplo, el error no se desencadena, pero al hacer una llamada del valor de myPointer, ¿ aún devuelve una dirección de memoria?
- ¿El # 3 realmente funciona? Parece que me funciona, el puntero ya no almacena una dirección, ¿es esta la manera correcta de borrar un puntero?
Perdón por la larga pregunta, quería dejar esto lo más claro posible, también para reiterar, tengo poca experiencia en programación, así que si alguien pudiera responder a esto usando términos comunes, ¡sería muy apreciado!
- Está intentando eliminar una variable asignada en la pila. No puedes hacer esto
- Eliminar un puntero no destruye un puntero en realidad, solo la memoria ocupada se devuelve al sistema operativo. Puede acceder a él hasta que la memoria se use para otra variable o se manipule de otra manera. Por lo tanto, es una buena práctica establecer un puntero a NULL (0) después de eliminar.
- Eliminar un puntero NULL no elimina nada.
Creo que no entiendes del todo cómo funcionan los punteros.
Cuando tiene un puntero apuntando a la memoria, hay tres cosas diferentes que debe comprender:
- hay "lo que apunta" por el puntero (la memoria)
- esta dirección de memoria
- no todos los punteros necesitan borrar su memoria: solo necesita borrar la memoria que fue asignada dinámicamente (se utilizó el new
operador).
Imagina:
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!
Cuando lo hiciste
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 ++ le permite intentar delete
un puntero que apunta a null
pero en realidad no hace nada, simplemente no da ningún error.
Los punteros son similares a las variables normales en que no es necesario eliminarlos. Se eliminan de la memoria al final de la ejecución de una función y / o al final del programa.
Sin embargo, puede utilizar punteros para asignar un ''bloque'' de memoria, por ejemplo, de esta manera:
int *some_integers = new int[20000]
Esto asignará espacio de memoria para 20000 enteros. Útil, porque el Stack tiene un tamaño limitado y es posible que desee jugar con una gran cantidad de ''ints'' sin un error de desbordamiento de la pila.
Siempre que llame a new, debe ''eliminar'' al final de su programa, ya que de lo contrario obtendrá una pérdida de memoria, y nunca se devolverá espacio de memoria asignado para que otros programas lo utilicen. Para hacer esto:
delete [] some_integers;
Espero que ayude.
1 y 2
myVar = 8; //not dynamically allocated. Can''t call delete on it.
myPointer = new int; //dynamically allocated, can call delete on it.
La primera variable fue asignada en la pila. Puede llamar a eliminar solo en la memoria asignada dinámicamente (en el montón) utilizando el new
operador.
3.
myPointer = NULL;
delete myPointer;
Lo anterior no hizo nada en absoluto . No has liberado nada, ya que el puntero apuntaba a NULL.
Lo siguiente no debe hacerse:
myPointer = new int;
myPointer = NULL; //leaked memory, no pointer to above int
delete myPointer; //no point at all
Lo apuntaste a NULL, dejando atrás la memoria filtrada (la nueva int que asignaste). Deberías liberar la memoria a la que apuntabas. Ya no hay forma de acceder a esa new int
asignada, por lo tanto, pérdida de memoria.
La forma correcta:
myPointer = new int;
delete myPointer; //freed memory
myPointer = NULL; //pointed dangling ptr to NULL
La mejor manera:
Si usa C ++, no use punteros sin formato. Use punteros inteligentes en su lugar, que pueden manejar estas cosas por usted con poca sobrecarga. C ++ 11 viene con several .
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.