¿Por qué es una mala práctica devolver un puntero a una variable o parámetro local? [duplicate]

4 minutos de lectura

Encontré esta pregunta en mi guía de estudio y no estoy seguro de por qué sería malo devolver un puntero a una variable/parámetro local. ¿Algunas ideas?

  • Consulte este stackoverflow.com/questions/4570366/pointer-to-local-variable

    – benipalj

    19 de noviembre de 2013 a las 5:06

  • Estas son todas buenas respuestas. No se cual elegir como mejor jaja. ¡Gracias chicos!

    –Steve

    19 de noviembre de 2013 a las 5:21

¿Por que es una mala practica devolver un puntero a
acercándoseoscuridadpeces

No es tanto una “mala práctica” (lo que implica que puede que causar problemas) tanto como es una práctica que causa absolutamente un comportamiento indefinido. Es como desreferenciar un puntero nulo: no lo haga y espere que su programa se comporte dentro de los límites de la lógica.

Explicación:

Cuando se declara una variable local (incluyendo un parámetro), se le da almacenamiento automáticolo que significa que el compilador se encarga de asignar memoria para la variable y luego desasignar esa memoria sin ningún esfuerzo por parte del programador.

void foo(int bar)
{
    int baz;
} //baz and bar dissappear here

Cuando finaliza el tiempo de vida de las variables (como cuando regresa la función), el compilador cumple su promesa y todas las variables automáticas que eran locales para la función se destruyen. Esto significa que cualquier puntero a esas variables ahora apunta a la memoria basura que el programa considera “libre” para hacer lo que quiera.

Al devolver un valor, esto no es un problema: el programa encuentra un nuevo lugar para poner el valor.

int foo(int bar)
{
    int baz = 6;
    return baz + bar; //baz + bar copied to new memory location outside of foo
} //baz and bar disapear

Cuando devuelve un puntero, el valor del puntero se copia normalmente. Sin embargo, el puntero aún apunta a la misma ubicación que ahora es basura:

int* foo(int bar)
{
    int baz = 6;
    baz += bar;
    return &baz; //(&baz) copied to new memory location outside of foo
} //baz and bar disapear! &baz is now garbage memory!

Acceder a esta memoria es un comportamiento indefinido, por lo que es casi seguro que su programa se comportará mal de una forma u otra. Por ejemplo, una vez fui víctima de este mismo problema, y ​​aunque mi programa no se bloqueó ni finalizó, mis variables comenzaron a degradarse a valores basura cuando el compilador sobrescribió la memoria “libre”.

1647730327 953 ¿Por que es una mala practica devolver un puntero a
nick t

Una vez que la función regresa, las variables y parámetros locales, que estaban en la pila, se han desasignado. Ellos mayo todavía existen, pero no hay garantías, y cuando algo decida usar la pila, seguramente será golpeado.

Usando el diagrama de WP:

Diagrama de pila

El puntero de la pila en la parte superior es donde se pueden asignar y colocar nuevas variables de forma segura (como cuando se llama a una función). Sin embargo, cuando la función (por ejemplo, DrawLine) regresa, se quitan de la pila (el puntero de la pila simplemente se incrementa, por lo que ya no apunta a variables verdes fuera del alcance). Cualquier cosa que venga más tarde y asigne y use espacio de pila destruirá los valores antiguos.

Porque voluntad causar un comportamiento indefinido en su programa.

Si devuelve un puntero a una variable local una vez que la función lo devuelve, está fuera del alcance. A partir de ese momento, es un comportamiento indefinido si accede al puntero devuelto.

Una variable local se almacena en la pila. Los valores almacenados en la pila se destruyen una vez que sale el bloque de función/código (es decir, llega al final de una función; técnicamente, pueden durar más, pero esa es otra discusión). Por lo tanto, el puntero (que apunta a una dirección en un lugar particular de la memoria) apunta a un valor que puede que ya no exista.

1647730328 912 ¿Por que es una mala practica devolver un puntero a
yamafontes

Porque la dirección de esa variable pertenece al marco de pila a partir del cual se creó. Nada más. Una vez tú returnese registro de activación se limpia y todo lo que estaba allí anteriormente ahora no está definido.

¿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