Pegadinha da realloc()

A função da biblioteca C padrão realloc() é normalmente utilizada para aumentar o tamanho de uma área de memória previamente alocada. Seu protótipo é:

void *realloc(void *ptr, size_t size);

Se a nova alocação é feita com sucesso, realloc() retorna um ponteiro para a nova área de memória (a qual contêm os mesmos dados da área anterior). Caso contrário a chamada retorna NULL, e a área anterior não é liberada.

A pegadinha acontece quando se acredita que realloc() nunca irá falhar, ou quando o programador simplesmente desconhece que em caso de falha a área anterior ainda é válida. Exemplo:

char *buf;
size_t size;

...

buf = malloc(size);

...

buf = realloc(buf, size*2);

Se realloc() falhar, ‘buf’ recebe NULL e você perde o ponteiro para a área anterior, a qual foi alocada com malloc() e ainda é válida. Ou seja, o resultado é um memory leak de ’size’ bytes. O código correto seria:

char *buf, *p;
size_t size;

...

buf = malloc(size);

...

p = realloc(buf, size*2);
if (!p) {
/* error handling */
...
free(buf);
return;
}
buf = p;

Há programadores que não se importam em consertar bugs como esse, eles argumentam que as funções da família alloc() raramente falham.

Não caia nesse conto, pois você não pode prever em quais máquinas e sob quais condições seu programa vai rodar.

Programas robustos costumam reagir bem a situações adversas, ou ao menos falham quando se espera que isso ocorra. Os mal escritos falham aleatoriamente em situações não esperadas, e apresetam bugs difíceis de reproduzir.

Sempre escreva código correto e robusto, você e seus usuários só tem a ganhar.

2 Responses to “Pegadinha da realloc()”

  1. Eu Says:

    Capitulino, essa sua dica é *muito boa*. Mas para ela ficar *ótima*, só falta ela sair publicada no CODARE (www.codare.net). Fala lá com o Aurélio e eu tenho certeza que você acaba publicando ela lá, ou que sabe, até acaba ficando como um membro permanente da equipe…

  2. lcapitulino Says:

    Obrigado!