C Erros Intermediário
Tratamento de erros
Em C, o tratamento de erros é manual e explícito. Diferente de linguagens com exceções, funções sinalizam falhas por códigos de retorno, pela variável global errno ou por assert. O programador deve verificar cada chamada que pode falhar e decidir o que fazer.
A biblioteca padrão usa errno para indicar o motivo exato da falha. Após uma chamada que retorna erro, você pode inspecionar errno ou usar perror para imprimir uma mensagem legível. É importante zerar errno antes da chamada, pois ele só é modificado em caso de erro.
Para bugs de programação, assert é útil: ele aborta o programa se a condição for falsa. Já para liberar recursos em cascata (memória, arquivos, sockets), o padrão goto com um bloco de limpeza é idiomático em C e evita vazamentos e código duplicado.
Pontos-chave
- Funções da biblioteca padrão retornam valores especiais (NULL, -1, 0) para indicar erro; sempre verifique.
errnoé uma variável global que armazena o código do último erro; useperrorpara uma mensagem descritiva.assert(condicao)aborta o programa se a condição for falsa; use apenas para bugs internos, não para validar entrada do usuário.- O padrão
goto cleanupcentraliza a liberação de recursos e evita vazamentos em múltiplos pontos de falha. - Sempre inicialize
errno = 0antes de chamar uma função que pode falhar, para não confundir erros antigos.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <assert.h>
// Função que aloca memória e copia string, tratando erros
char *duplica_string(const char *origem) {
assert(origem != NULL); // bug interno se origem for NULL
size_t tam = strlen(origem) + 1;
char *copia = malloc(tam);
if (copia == NULL) {
perror("malloc falhou"); // imprime mensagem do errno
return NULL;
}
memcpy(copia, origem, tam);
return copia;
}
int main(void) {
errno = 0; // zera errno antes de operações que podem falhar
char *s = duplica_string("Olá, mundo!");
if (s == NULL) {
fprintf(stderr, "Erro ao duplicar string.\n");
return EXIT_FAILURE;
}
printf("String duplicada: %s\n", s);
free(s);
return EXIT_SUCCESS;
}