Curso de C

Alocação Dinâmica

A alocação dinâmica permite ao programador criar variáveis em tempo de execução, ou seja, alocar memória para novas variáveis quando o programa está sendo executado. Esta é outra ferramenta que nos mostra o poder do C. O padrão C ANSI define apenas 4 funções para o sistema de alocação dinâmica, disponíveis na biblioteca stdlib.h:


No entanto, existem diversas outras funções que são amplamente utilizadas, mas dependentes do ambiente e compilador. Neste curso serão abordadas somente estas funções básicas. Consulte o manual de seu compilador para saber mais sobre as funções disponíveis para alocação dinâmica.

malloc

A função malloc() serve para alocar memória e tem o seguinte protótipo:

                void *malloc (unsigned int num);

A funçao toma o número de bytes que queremos alocar (num), aloca na memória e retorna um ponteiro void * para o primeiro byte alocado. O ponteiro void * pode ser atribuído a qualquer tipo de ponteiro. Se não houver memória suficiente para alocar a memória requisitada a função malloc() retorna um ponteiro nulo. Veja um exemplo de alocação dinâmica com malloc():

#include <stdio.h>

#include <stdlib.h>

main (void)

{

int *p;

int a;

... /* Determina o valor de a em algum lugar */

p=(int *)malloc(a*sizeof(int));

if (!p)

        {

        printf ("** Erro: Memoria Insuficiente **");

        exit;

        }

...

return 0;

}

No exemplo acima, é alocada memória suficiente para se colocar a números inteiros. O operador sizeof() retorna o número de bytes de um inteiro. Ele é util para se saber o tamanho de tipos. O ponteiro void* que malloc() retorna é convertido para um int* pelo cast e é atribuído a p. A declaração seguinte testa se a operação foi bem sucedida. Se não tiver sido, p terá um valor nulo, o que fará com que !p retorne verdadeiro. Se a operação tiver sido bem sucedida, podemos usar o vetor de inteiros alocados normalmente, por exemplo, indexando-o de p[0] a p[(a-1)].

calloc

A função calloc() também serve para alocar memória, mas possui um protótipo um pouco diferente:

                void *calloc (unsigned int num, unsigned int size);

A funçao aloca uma quantidade de memória igual a num * size, isto é, aloca memória suficiente para uma matriz de num objetos de tamanho size. Retorna um ponteiro void * para o primeiro byte alocado. O ponteiro void * pode ser atribuído a qualquer tipo de ponteiro. Se não houver memória suficiente para alocar a memória requisitada a função calloc() retorna um ponteiro nulo. Veja um exemplo de alocação dinâmica com calloc():

#include <stdio.h>

#include <stdlib.h>

main (void)

{

int *p;

int a;

...

p=(int *)calloc(a, sizeof(int));

if (!p)

        {

        printf ("** Erro: Memoria Insuficiente **");

        exit;

        }

...

return 0;

}

No exemplo acima, é alocada memória suficiente para se colocar a números inteiros. O operador sizeof() retorna o número de bytes de um inteiro. Ele é util para se saber o tamanho de tipos. O ponteiro void * que calloc() retorna é convertido para um int * pelo cast e é atribuído a p. A declaração seguinte testa se a operação foi bem sucedida. Se não tiver sido, p terá um valor nulo, o que fará com que !p retorne verdadeiro. Se a operação tiver sido bem sucedida, podemos usar o vetor de inteiros alocados normalmente, por exemplo, indexando-o de p[0] a p[(a-1)].

realloc

A função realloc() serve para realocar memória e tem o seguinte protótipo:

                void *realloc (void *ptr, unsigned int num);

A funçao modifica o tamanho da memória previamente alocada apontada por *ptr para aquele especificado por num. O valor de num pode ser maior ou menor que o original. Um ponteiro para o bloco é devolvido porque realloc() pode precisar mover o bloco para aumentar seu tamanho. Se isso ocorrer, o conteúdo do bloco antigo é copiado no novo bloco, e nenhuma informação é perdida. Se ptr for nulo, aloca size bytes e devolve um ponteiro; se size é zero, a memória apontada por ptr é liberada. Se não houver memória suficiente para a alocação, um ponteiro nulo é devolvido e o bloco original é deixado inalterado.

free

Quando alocamos memória dinamicamente é necessário que nós a liberemos quando ela não for mais necessária. Para isto existe a função free() cujo protótipo é:

                void free (void *p);

Basta então passar para free() o ponteiro que aponta para o início da memória alocada. Mas você pode se perguntar: como é que o programa vai saber quantos bytes devem ser liberados? Ele sabe pois quando você alocou a memória, ele guardou o número de bytes alocados numa "tabela de alocação" interna. Vamos reescrever o exemplo usado para a função malloc() usando o free() também agora:

#include <stdio.h>

#include <alloc.h>

main (void)

{

int *p;

int a;

...

p=(int *)malloc(a*sizeof(int));

if (!p)

        {

        printf ("** Erro: Memoria Insuficiente **");

        exit;

        }

...

free(p);

...

return 0;

}

 


AUTO AVALIAÇÃO

Veja como você está. Refaça o exemplo desta página, mas ao invés de trabalhar com um vetor de inteiros, use um vetor de strings (ou uma matriz de char, como você preferir). Faça leituras e apresente os resultados na tela.

Página Anterior Índice da Aula Próxima Página


Curso de C do CPDEE/UFMG - 1996 - 1999