setjmp
Diferencias
Muestra las diferencias entre dos versiones de la página.
| Próxima revisión | Revisión previa | ||
| setjmp [2012/08/23 03:38] – creado lmateu | setjmp [2016/11/22 12:56] (actual) – [Manejo de errores] lmateu | ||
|---|---|---|---|
| Línea 6: | Línea 6: | ||
| de una función a otra función más abajo en la pila de llamadas | de una función a otra función más abajo en la pila de llamadas | ||
| a funciones. | a funciones. | ||
| + | |||
| + | Por ejemplo, si se busca un dato específico en un árbol binario no ordenado, esta búsqueda es recursiva. | ||
| + | Sin excepciones esto no se puede hacer: hay que retornar de cada una de las llamadas recursivas. | ||
| + | en C setjmp y longjmp. | ||
| + | de la ejecución. | ||
| + | |||
| + | Esta es la solución para el caso de una busqueda recursiva en un árbol binario no ordenado. | ||
| < | < | ||
| Línea 50: | Línea 57: | ||
| Es importante que la función destinataria del salto no haya retornado aún. De otra forma | Es importante que la función destinataria del salto no haya retornado aún. De otra forma | ||
| los efectos son impredecibles. | los efectos son impredecibles. | ||
| - | la primera vez que se invoca | + | la primera vez que se invoca |
| se invoca longjmp. | se invoca longjmp. | ||
| - | retorno, el valor es lo que se especificó como parámetro | + | retorno, el valor es lo que se especificó como argumento |
| que sea distinto de 0 para poder distinguirlo del primer retorno. | que sea distinto de 0 para poder distinguirlo del primer retorno. | ||
| + | |||
| + | ==== Manejo de errores ==== | ||
| + | |||
| + | La funciones setjmp y longjmp se usan sobretodo para manejar situaciones de error, al igual que las excepciones. | ||
| + | |||
| + | < | ||
| + | jmp_buf env; | ||
| + | int main() { | ||
| + | for(;;) { | ||
| + | if (setjmp(env)==0) { | ||
| + | char buf[80]; | ||
| + | int leidos= fread(buf, 1, 80, stdin); | ||
| + | if (leidos==0) | ||
| + | break; | ||
| + | procesar(buf, | ||
| + | } | ||
| + | } | ||
| + | return 0; | ||
| + | } | ||
| + | | ||
| + | void procesar(char *buf, int n) { ... f(); ... } | ||
| + | void f() { ... g(); ... } | ||
| + | void g() { ... h(); ... } | ||
| + | | ||
| + | void h() { | ||
| + | ... | ||
| + | if (x> | ||
| + | fprintf(stderr, | ||
| + | longjmp(env, | ||
| + | } | ||
| + | ... | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | De esta forma el programa puede seguir procesando comandos en vez de terminar abruptamente el programa o alternativamente manejar la condición de error en g, h, procesar, etc. | ||
| + | |||
| + | El inconveniente de este enfoque es que si la función f pidió memoria o abrió un archivo que tenía que liberar o cerrar al retornar, si ocurre el error la memoria y el archivo abierto se transformarán en goteras. | ||
| + | |||
| + | ==== Discusión ==== | ||
| Hay que reconocer que el funcionamiento de setjmp y longjmp es | Hay que reconocer que el funcionamiento de setjmp y longjmp es | ||
setjmp.1345693102.txt.gz · Última modificación: por lmateu
