Autor
|
Tema: No devolver nunca punteros a variables locales a una función en c (Leído 4,642 veces)
|
eduu15
Desconectado
Mensajes: 17
|
No entiendo muy bien este concepto y he estado pensando acerca del tema. Aclarar que el codigo funciona pero no estoy seguro de que sea correcto #include <stdio.h>
int* funcion () { int resultado=9; //variable local de la funcion, al acabar la funcion se pierde el dato int*puntero=&resultado; //cuando termine la funcion puntero no sabra a donde apuntar
return *puntero; //devuelvo el valor de resultado }
int main(int argc, char *argv[]) { int* p=funcion(); printf("%i",p); //9
return 0; } Si he comentado mal el programa por favor comentenlo, yo creo que aunque funcione seria incorrecto, porque una vez acabe la funcion, puntero no sabra a donde apuntar y podrian sobreescribirse direcciones de memoria. Ustedes que opinan?
|
|
« Última modificación: 11 Abril 2018, 09:08 am por eduu15 »
|
En línea
|
|
|
|
Yuki
Desconectado
Mensajes: 80
El error es una muestra de la incompetencia.
|
Efectivamente la variable "p" apunta a la pila que puede ser sobreescrita.
Es más, creo que si establecieras un par de argumentos más a "printf" el valor seria reemplazado.
|
|
|
En línea
|
|
|
|
eduu15
Desconectado
Mensajes: 17
|
Acabo de hacer la prueba y no se esta sobreescibiendo probado en windows y ubuntu curioso el tema
|
|
|
En línea
|
|
|
|
Yuki
Desconectado
Mensajes: 80
El error es una muestra de la incompetencia.
|
Estuve depurando y resulta que tu función retorna el valor "9" entero, no un puntero a la variable. El ejemplo correcto seria el siguiente: #include <stdio.h>
int funcion () { int resultado=9; //variable local de la funcion, al acabar la funcion se pierde el dato return (int)&resultado; }
int main(int argc, char *argv[]) { int* p = (int*)funcion(); printf("%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i",1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,*p); //9
return 0; } Que de todas formas no funciona debido a la manera que tiene el compilador de generar el código. ¿Como lo hace? Básicamente preserva TODA la memoria necesaria en la pila para empujar los argumentos al arrancar el main, esto evita que se corrompa la pila al invocar funciones privadas y de tipo CDECL. Esto es con DevC++.
|
|
|
En línea
|
|
|
|
eduu15
Desconectado
Mensajes: 17
|
Ok, gracias Yuki
|
|
|
En línea
|
|
|
|
MAFUS
Desconectado
Mensajes: 1.603
|
Como te han dicho no has devuelto el puntero sino el valor al que apunta. Eso ha pasado por añadir el asterisco a la variable del return. Todavía tienes ahí lío con los operadores de punteros.
Ahora cuidado porque ese valor devuelto ha sido recogido por el puntero p de main y eso quiere decir que ahora apunta a la dirección 9. El programa ha funcionado porque en printf le has pedido la dirección a la que apunta, de haber querido acceder a su contenido el S.O. te habría detenido.
Respondiendo a tu pregunta: cuando se llama a una función previamente se forma un marco de esa función en la pila dónde se encuentran los argumentos, la dirección de retorno y todas las variables locales y el puntero de pila se mueve al final de todo. Cuando una función termina se devuelve el puntero de pila al inicio de todo eso, eso es al final de la función llamante, por esa razón esa memoria que hay después ya no es accesible.
Aunque eso último es mentira. Si devuelves un puntero a una variable local sigues apuntando en esa dirección de memoria que el sistema ya no puede tocar. Es posible y se te permite trabajar allí y mientras no llames a otra función esa memoria no se va a tocar y te parecerá válido lo que hagas. En el momento que llames a otra función harás que la pila aloje datos allí perdiendo todo loque hayas hecho.
Y sí, si me pasas ese puntero a la función puede corromperse a sí misma pues tendrá un puntero que apunta a una zona indeterminada de su marco.
|
|
|
En línea
|
|
|
|
eduu15
Desconectado
Mensajes: 17
|
Entonces la conclusion es que aunque el SO te lo permita mejor no hacerlo
Aunque la primera funcion no tenga sentido ya que devuelve un int no un puntero a int esta parte
return *puntero; es como si hiciese return resultado no? estaria desreferenciando el puntero
|
|
« Última modificación: 11 Abril 2018, 15:56 pm por eduu15 »
|
En línea
|
|
|
|
MAFUS
Desconectado
Mensajes: 1.603
|
Así es, dereferencias el puntero antes de devolverlo. Pero lo dicho. Lo recibe un puntero así que a partir de ese momento estás apuntando a la dirección 9 de la memoria.
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
devolver valor de uan funcion
Programación C/C++
|
mapers
|
1
|
2,747
|
15 Noviembre 2010, 05:14 am
por Mr.Blue
|
|
|
Devolver un vector en una funcion
Programación C/C++
|
d00ze13
|
5
|
25,190
|
12 Enero 2011, 09:41 am
por leogtz
|
|
|
Devolver varias variables en una sola función
« 1 2 »
Programación C/C++
|
javirk
|
15
|
20,395
|
29 Enero 2012, 18:20 pm
por qerde
|
|
|
Devolver cadena con función
Programación C/C++
|
Kaxperday
|
7
|
3,475
|
6 Agosto 2014, 05:55 am
por leosansan
|
|
|
[Aporte]Return en php - Devolver variables y arreglos desde funciones en PHP
PHP
|
korko
|
0
|
2,441
|
7 Febrero 2021, 05:28 am
por korko
|
|