¿Qué es una referencia colgante?

9 minutos de lectura

¿Que es una referencia colgante
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...   
}

  • “¿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


1647533710 657 ¿Que es una referencia colgante
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.

  • +(1/2) para esta respuesta. La explicación inicial es buena. El consejo al final es paranoico e innecesario. El código del OP es seguro.

    – Benjamín Lindley

    1 de agosto de 2013 a las 14:55


  • @BenjaminLindley … y temerario e innecesariamente inseguro. Trabajando alrededor std::string con strdup es simplemente ridículo.

    – R. Martinho Fernández

    1 de agosto de 2013 a las 14:59


  • @Jack ¿Cómo diablos podría new_foo acceder al parámetro de función de foo para modificarlo? El ejemplo del OP es seguro.

    – Angew ya no está orgulloso de SO

    01/08/2013 a las 15:00

  • @codemuncher: global_name se convierte en un puntero colgante cuando foo devuelve, porque la cadena desde la que se originó el puntero (string name en foo) se destruye en ese momento.

    – Benjamín Lindley

    1 de agosto de 2013 a las 15:26

  • @codemuncher No estoy seguro de lo que quieres hacer “de forma segura”. La regla es simple: todos los punteros deben ser nulos o apuntar a un “objeto” válido. (Estoy usando “objeto” en el sentido en que se usa en el estándar de C++). Cuando elimina algo, debe asegurarse (por diseño) de que no siga existiendo ningún puntero hacia él. Y con respecto al valor de retorno de std::string::c_str(): los solamente El momento en que debe usar esta función es cuando se conecta a una función heredada que requiere un char const*.

    – James Kanze

    2 de agosto de 2013 a las 8:04

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.

  • @Miklós Homolya es “const”… ¡¿a qué te refieres con modificar en new_foo?!

    – masticador de códigos

    1 de agosto de 2013 a las 15:14

  • Ese uso de “const” es una función de front-end (compilador), que podría ser superada por un const_cast. El problema es cómo obtener, de manera compatible con el estándar, una referencia a la variable de pila ‘nombre’, porque el código de la función ‘foo’ ya está dado.

    usuario2545918

    1 de agosto de 2013 a las 15:33

  • no creo new_foo puede cambiar el nombre

    – Deqing

    01/08/2013 a las 15:35

1647533711 740 ¿Que es una referencia colgante
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

ingrese la descripción de la imagen aquí

Luego

ingrese la descripción de la imagen aquí

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.

  • El ‘puntero colgante’ es uno de los problemas más perniciosos en C, y es una de las razones por las que C++ creó referencias. Lamentablemente, las referencias pueden volverse colgantes de la misma manera. Punteros inteligentes (en.wikipedia.org/wiki/Smart_pointer) son una forma de abordar el problema. Desafortunadamente, el comportamiento resultante no está definido, por lo que a veces el resultado se convertirá en ‘basura’ (si otra parte del programa usa esa área de memoria), y otras veces no. Esto conduce al tipo de error difícil de replicar que hace que la gente se arranque los pelos.

    – dana

    17 mayo 2018 a las 23:18


  • @Yatin, editó una cita, aunque no está en el formato de cita, tiene el enlace de donde se tomó, tenga cuidado con eso.

    – anastaciú

    10 de agosto de 2020 a las 10:18

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.

1647533713 169 ¿Que es una referencia colgante

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.

1647533714 532 ¿Que es una referencia colgante

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.

1647533714 615 ¿Que es una referencia colgante

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.

1647533715 784 ¿Que es una referencia colgante
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

1647533715 621 ¿Que es una referencia colgante
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

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad