2012-01-05 27 views
13

Decir que tengo las siguientes dos funciones:Dirección de devolución de variable local en C

int * foo() 
{ 
    int b=8; 
    int * temp=&b; 
    return temp; 
} 

int * foo() 
{ 
    int b=8; 
    return &b; 
} 

que no recibe ninguna advertencia para el primero (por ejemplo, la función devuelve la dirección de una variable local) pero yo kn Esto es ilegal ya que b desaparece de la pila y nos queda un puntero a la memoria indefinida.

Entonces, ¿cuándo debo tener cuidado al devolver la dirección de un valor temporal?

Respuesta

17

La razón por la que no recibe una advertencia en el primer fragmento es porque no está (desde la perspectiva del compilador) devolviendo una dirección a una variable local.

Regresa el valor de int * temp. Aunque esta variable podría ser (y en este ejemplo es) que contiene un valor que es una dirección de una variable local, el compilador no irá a la pila de ejecución de código para ver si este es el caso.

Nota: Ambos fragmentos son igual de malo, a pesar de que su compilador no le advierte sobre la primera. No use este enfoque.


Siempre se debe tener cuidado al volver a direcciones variables locales; como regla, podría decir que nunca debería.

static Las variables son un caso completamente diferente, que se está discutiendo en this thread.

+1

gracias! y el hecho de que cuando imprimo el valor de retorno en main me da el resultado correcto, ¿realmente significa que imprime basura? – mary

+3

Significa que está invocando lo que normalmente nos referimos como * [comportamiento indefinido] (http://en.wikipedia.org/wiki/Undefined_behavior) *, es decir. comportamiento que no está especificado en el estándar. –

-2

Ambos son malos, y un buen compilador debería ser capaz de detectar y advertir sobre ambas situaciones. Puede obtener mejores resultados al activar el nivel de advertencia al máximo (que siempre debe hacer de todos modos) y activar la optimización.

+0

El caso específico, tal vez. Pero hay muchos casos similares que implican mezclar la dirección ay desde otras variables (o mediante otras funciones) que un compilador simplemente no podrá detectar. Además, la optimización rara vez aumenta las posibilidades de detectar un problema de este tipo, sino que aumenta la probabilidad de que el problema tenga efectos observables. – Rob

+0

Por supuesto, hay situaciones que el compilador no puede detectar, pero estos casos específicos deben ser fácilmente detectables. La optimización funciona porque reduce el primer ejemplo al segundo. – harald

+1

Lo siento, no es cierto. Hay pocos "requisitos" cuando se trata de la calidad de la implementación de un compilador: estas decisiones de los proveedores se basan en su propio análisis de costo/beneficio, que puede no cumplir con las ideas preconcebidas de los desarrolladores. También es muy fácil construir ejemplos (por ejemplo, una llamada a una función que puede cambiar el puntero), lo que significa que la optimización que usted reclama puede no ser factible, lo que también hace que el proveedor decida si optimiza o no esas cosas, no una determinada. – Rob

0

Ambos ejemplos son igualmente incorrectos. Supongo que su compilador no ve el peligro y, por lo tanto, no emite una advertencia cuando almacena la dirección en una variable temporal.

1

diría que puede devolver la variable local o más bien punteros a tal IF si fue asignada dinámicamente por malloc, en ese caso la memoria utilizada para almacenar variable quiere estar en la pila pero en el montón y no se borrará o reutilizado después de salir de la función como se lleva a cabo en el caso de variables locales automáticas (creadas sin malloc), ¿estoy en lo correcto?

0

Esta pregunta es probablemente una de las más discutidas en StackO. A continuación, hay dos respuestas de hilos similares en StackO que me parecieron interesantes, y probablemente me hicieron abandonar esta mala práctica de desreferenciar las variables locales a pesar de que las posibilidades de que me equivoque (comportamiento indefinido) son muy escasas.

Here is a simple answer

Me gustó especialmente la esta respuesta.

Here is an example where this bad practice caused some real hardware damage

Cuestiones relacionadas