C/errno: Diferenzas entre revisións

Contido eliminado Contido engadido
Gallaecio (conversa | contribucións)
m Programación en C/Manexo de erros movida a C/Manexo de erros
Gallaecio (conversa | contribucións)
Sen resumo de edición
Liña 6:
 
O seguinte código examina o valor a devolver pola función da biblioteca <code>malloc</code> para ver se a asignación dinámica de memoria se completa axeitadamente:
<source lang="c">
#include <stdio.h> // fprintf
#include <errno.h> // errno
#include <stdlib.h> // malloc, free, exit
#include <string.h> // strerror
 
extern int errno;
<font style="color:#bc5ff8">#include</font> <font style="color:#ff48ff"><stdio.h></font> <font style="color:blue">// fprintf</font>
 
<font style="color:#bc5ff8">#include</font> <font style="color:#ff48ff"><errno.h></font> <font style="color:blue">// errno</font>
int main(void)
<font style="color:#bc5ff8">#include</font> <font style="color:#ff48ff"><stdlib.h></font> <font style="color:blue">// malloc, free, exit</font>
{
<font style="color:#bc5ff8">#include</font> <font style="color:#ff48ff"><string.h></font> <font style="color:blue">// strerror</font>
'''<font style="color:#1b991b">extern int</font>''' errno;
'''<font style="color:#1b991b">int</font>''' main('''<font style="color:#1b991b">void</font>''')
{
<font style="color:blue">/********************************************************************
* En referencia a carácteres, solicitude de asignación dinámica de *
* 2.000.000.000 de elementos de almacenaxe (declarados coma un *
* número enteiro constante de tipo unsigned long int). (Se o teu *
* sistema ten menos de 2 GB de memoria dispoñibles, esta chamada *
* a malloc fallará. *
********************************************************************/</font>
'''<font style="color:#1b991b">char</font>''' *ptr = malloc(<font style="color:#ff48ff">2000000000UL</font>);
'''<font style="color:#bb2323">if</font>''' ( ptr == <font style="color:#ff48ff">NULL</font> ) <font style="color:blue">// Máis adiante veremos o que son os punteiros (ptr) e como usalos axeitadamente</font>
puts(<font style="color:#ff48ff">"malloc fallou"</font>);
'''<font style="color:#bb2323">else</font>'''
{
<font style="color:blue">/*********************************************************************
* O resto do código a partires da aquí pode asumir que se asignarán *
* 2.000.000.000 de carácteres satisfactoriamente... *
*********************************************************************/</font>
free(ptr); <font style="color:blue">// Isto, como xa veremos máis adiante, libera a memoria reservada</font>
}
exit(SAIDA_SATISFACTORIA); <font style="color:blue">// Saída do programa</font>
}
 
/********************************************************************
* En referencia a carácteres, solicitude de asignación dinámica de *
* 2.000.000.000 de elementos de almacenaxe (declarados coma un *
* número enteiro constante de tipo unsigned long int). (Se o teu *
* sistema ten menos de 2 GB de memoria dispoñibles, esta chamada *
* a malloc fallará. *
********************************************************************/
char *ptr = malloc(2000000000UL);
 
if ( ptr == NULL ) // Máis adiante veremos o que son os punteiros (ptr) e como usalos axeitadamente
puts("malloc fallou");
else
{
/*********************************************************************
* O resto do código a partires da aquí pode asumir que se asignarán *
* 2.000.000.000 de carácteres satisfactoriamente... *
*********************************************************************/
free(ptr); // Isto, como xa veremos máis adiante, libera a memoria reservada
}
 
exit(SAIDA_SATISFACTORIA); // Saída do programa
}
</source>
O anterior fragmento de código amosa o uso do valor devolto pola función da biblioteca <code>malloc</code> para buscar erros. Moitas funcións de bibliotecas devolven valores que marcan erros, e deste xeito debería ser comprobado polo astuto programador. No fragmento de código, un punteiro nulo (<code>NULL</code>) devolveu dos sinais de <code>malloc</code> un erro na asignación, polo que se saíu do programa. En implementacións máis complicadas, o programa podería tratar de manexar o erro e tratar de recuperarse da asignación de memoria fallida.
 
==Manexo de erros ao dividir por cero==
Un erro habitual cometido polos programadores en C é o de non comprobar se un divisor é cero antes dun comando de división. O seguinte código produce un erro de procesamento, e a miúdo a saída do programa.
<source lang="c">
 
int dividend = 50;
'''<font style="color:#1b991b">int</font>''' dividend = <font style="color:#ff48ff">50</font>;
int divisor = 0;
'''<font style="color:#1b991b">int</font>''' divisor = <font style="color:#ff48ff">0</font>;
'''<font style="color:#1b991b">int</font>''' quotient;
quotient = (dividend/divisor); <font style="color:blue">// Isto producirá un erro de execución!
</fontsource>
 
Por razóns alén dos obxectivos deste capítulo (e que non se van explicar en ningún outro deste libro) debes comprobar que ningún divisor sexa nunca cero. De forma alternativa, para procesos UNIX (e baseados coma Linux), podes evitar que o sistema remate o teu proceso bloqueando a sinal SIGFPE.
 
O seguinte código arranxa isto comprobando o divisor antes de utilizalo na división:
<source lang="c">
#include <stdio.h> // fprintf e stderr
#include <stdlib.h> // Para a saída
 
int main(void)
<font style="color:#bc5ff8">#include</font> <font style="color:#ff48ff"><stdio.h></font> <font style="color:blue">// fprintf e stderr</font>
{
<font style="color:#bc5ff8">#include</font> <font style="color:#ff48ff"><stdlib.h></font> <font style="color:blue">// Para a saída</font>
int dividend = 50;
int divisor = 0;
'''<font style="color:#1b991b">int</font>''' main('''<font style="color:#1b991b">void</font>''')
int quotient;
{
 
'''<font style="color:#1b991b">int</font>''' dividend = <font style="color:#ff48ff">50</font>;
if (divisor == 0)
'''<font style="color:#1b991b">int</font>''' divisor = <font style="color:#ff48ff">0</font>;
{
'''<font style="color:#1b991b">int</font>''' quotient;
/***********************************************************
* Exemplo de manexo deste erro. Escríbeselle unha mensaxe *
'''<font style="color:#bb2323">if</font>''' (divisor == <font style="color:#ff48ff">0</font>)
* a stderr, e sáese cun erro. *
{
<font style="color:blue">/***********************************************************/
fprintf(stderr, "Unha división por cero! Abortando...\n");
* Exemplo de manexo deste erro. Escríbeselle unha mensaxe *
exit(SAIDA_ERRO); // Indica que houbo un erro
* a stderr, e sáese cun erro. *
}
***********************************************************/</font>
 
fprintf(stderr, <font style="color:#ff48ff">"Unha división por cero! Abortando...</font><font style="color:#a7a0d7">\n</font><font style="color:#ff48ff">"</font>);
quotient = (dividend/divisor);
exit(SAIDA_ERRO); <font style="color:blue">// Indica que houbo un erro</font>
exit(EXIT_SUCCESS); // Indica que todo foi ben
}
}
</source>
quotient = (dividend/divisor);
exit(EXIT_SUCCESS); <font style="color:blue">// Indica que todo foi ben</font>
}