
masticador de código
Sé que esta es una pregunta bastante común, ¡pero sigue siendo nueva para mí!
No entiendo el concepto de puntero colgante, estaba buscando en Google y escribiendo métodos de prueba para encontrar uno.
Me pregunto si esto es un puntero colgante. Como cualquier ejemplo que encontré estaba devolviendo algo, ¡aquí estoy intentando algo similar!
¡Gracias!
void foo(const std::string name)
{
// will it be Dangling pointer?!, with comments/Answer
// it could be if in new_foo, I store name into Global.
// Why?! And what is safe then?
new_foo(name.c_str());
}
void new_foo(const char* name)
{
// print name or do something with name...
}

Jack
Un puntero colgante es un puntero que apunta a datos no válidos o que ya no son válidos, por ejemplo:
Class *object = new Class();
Class *object2 = object;
delete object;
object = nullptr;
// now object2 points to something which is not valid anymore
Esto puede ocurrir incluso en objetos asignados a la pila:
Object *method() {
Object object;
return &object;
}
Object *object2 = method();
// object2 points to an object which has been removed from stack after exiting the function
El puntero devuelto por c_str
puede volverse inválido si la cadena se modifica posteriormente o se destruye. En tu ejemplo, parece que no lo modificas, pero como no está claro qué vas a hacer con const char *name
es imposible saber si su código es intrínsecamente seguro o no.
Por ejemplo, si almacena el puntero en algún lugar y luego se destruye la cadena correspondiente, el puntero deja de ser válido. Si utiliza const char *name
justo en el ámbito de new_foo
(por ejemplo, con fines de impresión), el puntero seguirá siendo válido.
Un puntero colgante es un puntero (no NULL) que apunta a un área de memoria no asignada (ya liberada).
El ejemplo anterior debería ser correcto dado que la cadena no se modifica a través de new_foo.

Ashish Ahuja
Tomado de aquí. Aunque, incluso si esto es para C, es lo mismo para C++.
Puntero colgante
Cuando un puntero apunta a la dirección de memoria de una variable, pero después de un tiempo esa variable se elimina de esa ubicación de memoria mientras el puntero aún apunta a ella, dicho puntero se conoce como puntero colgante y este problema se conoce como el Problema del puntero colgante.
Inicialmente

Luego

Ejemplo
#include<stdio.h>
int *call();
int main() {
int *ptr;
ptr = call();
fflush(stdin);
printf("%d", *ptr);
return 0;
}
int * call() {
int x=25;
++x;
return &x;
}
Su salida será basura porque la variable x
es una variable local. Su alcance y duración están dentro de la llamada de función, por lo tanto, después de devolver la dirección de x
variable x
queda muerto y el puntero sigue apuntando a esa ubicación.
Como cuestión de estilo, explico un puntero colgante como “un puntero que todavía existe, aunque el objeto al que apuntaba ya no existe”.
En tu caso, el puntero name
existe por un período más corto que el objeto al que apunta. Así que nunca está colgando.
Dentro de las clases comunes de C++, los punteros cuelgan durante un período muy corto, dentro de los destructores. Eso es porque el delete
declaración es antes de la última }
del destructor, mientras que el puntero mismo deja de existir en el último }
. Si no quiere preocuparse por esto, use por ejemplo unique_ptr<T>
. los T*
puntero colgará durante un tiempo muy corto dentro de la unique_ptr::~unique_ptr
destructor, que es perfectamente seguro.
Los punteros colgantes son una situación en la que tiene punteros válidos en la pila, pero apunta a una memoria no válida. Puede terminar en esta situación cuando desasigna la memoria del montón antes de que se desasignen los punteros en la pila.

Este es un problema de seguridad. Porque cuando desasignas una memoria, le informamos al sistema operativo que ya no necesitamos esta sección de memoria. Entonces, el sistema operativo marcará esa parte de la memoria como lista para asignar y asignará a otras aplicaciones cuando soliciten memoria.
Por lo general, en C++, la memoria se asigna y desasigna a través de un patrón general. El constructor en una clase se invoca cuando se inicializa una clase y este es el lugar correcto para asignar memoria en el montón. Supongamos que ya creamos una clase que asigna y desasigna memoria en constructor y destructor respectivamente.
int main() {
SomeClass pointer1 = SomeClass();
SomeClass pointer2 = pointer1;
}
En el código de ejemplo anterior, hay dos variables declaradas, pero ambas tienen el mismo valor. Cuando se invoca el constructor, asigna una memoria de almacenamiento dinámico. Entonces estamos declarando una variable más y asignando el mismo valor. En C ++, por lo general, cuando asigna un valor de tipo complejo, hace una copia superficial (a menos que haya implementado explícitamente el constructor de copias) en lugar de una copia profunda. Eso significa que el único puntero se copia en Stack, pero no la memoria del montón. En realidad, no se recomienda copiar la memoria del montón por motivos de rendimiento. Ahora, el diseño final de la memoria parece que tenemos dos punteros que apuntan a la misma memoria de almacenamiento dinámico.

Ahora, cuando la función termina con la ejecución, las variables locales quedan fuera del alcance e invoca al destructor. Primero, pointer2 invoca al destructor que desasigna la memoria del montón. En este punto, puntero1 se convierte en puntero colgante. Apunta a una memoria que ya está desasignada.

A partir de este ejemplo, entendimos que la causa principal del puntero colgante es tener varios propietarios para el mismo recurso. Porque cuando un puntero desasigna memoria, otros punteros se convierten en punteros colgantes.

Sadia Younas
//Declaring two pointer variables to int
int * ptr1;
int * ptr2;
// Allocating dynamic memory in the heap
ptr1 = new int;
ptr2 = ptr1; // Having both pointers to point same dynamic memory location
//deleting the dynamic memory location
delete ptr1;
ptr1 = nullptr;
//ptr2 is still pointing the already deleted memory location
//We call ptr2 is a dangling pointer

J. Chomel
Puntero colgante y problema de puntero colgante Si algún puntero apunta a la dirección de memoria de cualquier variable pero después de que alguna variable se haya eliminado de esa ubicación de memoria mientras el puntero sigue apuntando a dicha ubicación de memoria.
Ese puntero se denomina puntero colgante y el problema que surge en ese momento se denomina problema del puntero colgante.
Aquí hay unos ejemplos: Puntero colgante y problema de puntero colgante
“¿Será un puntero colgante?!, con comentarios/Respuesta es” — No, no es. No hay un puntero colgante en su primer ejemplo. Lo que estás haciendo allí es perfecto, 100% seguro y correcto.
– Benjamín Lindley
01/08/2013 a las 15:00
No veo cómo puedes tener un puntero colgante … sin el puntero.
– gifnoc-gkp
1 de agosto de 2013 a las 15:01
@TheOtherGuy Quiero decir, no const char* … llevando la misma const std::string
– masticador de códigos
1 de agosto de 2013 a las 15:03
@BenjaminLindley bueno, desde la respuesta de Jack, parece cierto, ya que c_str() devuelve el puntero a la cadena, lo que puede no ser válido en new_foo … ¡podría estar mal!
– masticador de códigos
1 de agosto de 2013 a las 15:05
Nota: edité el tipo de retorno de
foo
para no parecer tonto por decir que lo que está haciendo es 100% seguro y correcto.– Benjamín Lindley
1 de agosto de 2013 a las 15:37