22 de jun. de 2010

Alocação de Dinâmica de Memória em C

image

Quando falamos em listas, uma das soluções plausíveis para implementar esta estrutura de dados é dada usando vetores. Porém temos que alocar uma capacidade máxima para este vetor, o que, de certa forma, torna a aplicação limitada.

A linguagem C permite a alocação dinâmica de memória. Um dos responsáveis por isso é a função malloc(). Essa função permite alocar uma determinada quantidade de bytes e retorna o ponteiro para esta região alocada na memória. É interessante trabalhar a alocação dinâmica de memória usando os três conceitos a seguir:

  • malloc(): Função que aloca memória de um determinado tamanho e retorna o ponteiro para ela.
  • free(): Libera a memória alocada dinamicamente, bastando informar o ponteiro dela.
  • sizeof(): Mede o tamanho de um determinado tipo, inclusive de uma struct.

A memória que o malloc() aloca é da Heap. A Heap é uma porção e memória que o SO dedica ao aplicativo para esta natureza de alocação.

Uma consideração importante sobre o malloc() está no quesito de conversão explicita (cast), pois quando alocamos memória, o malloc() retorna um ponteiro, mas não se sabe do que é este ponteiro. Então podemos explicitar de que tipo de trata o ponteiro.

Para compreender melhor, acompanhe os exemplos a seguir:

#include <conio.h>
#include <stdio.h>
#include <stdlib.h>

void main()
{
    int *inteiro = (int *)malloc(sizeof(int)); 

    *inteiro = 10;

    printf("\n tamanho de mem0ria alocado %i", sizeof(int));
    printf("\n endereco de memoria %x", inteiro);
    printf("\n valor dentro do endereco de memoria %i", *inteiro);

    free(inteiro);

    getch();
}

image

Primeiramente, notamos que obrigatoriamente temos usar um ponteiro, pois é isso que o malloc() retorna.

O cast (conversão explicita) fica por conta do: (int *) – onde indicamos que o ponteiro na verdade é um ponteiro para um inteiro.

Utilizamos também o sizeof() para medir o tamanho, em bytes, que um inteiro ocupa na memória. Podemos definir este valor “na unha”, caso necessário. Podemos inclusive montar um array dinâmico, multiplicando o sizeof() pelo tamanho desejado.

Antes de testarmos mais a alocação de memória temos de dar extrema importância ao free(). Esta função que é responsável por liberar memória. Portanto: lembre-se de usá-la. É importante para um uso otimizado de memória.

Bastante deve ser o cuidado ao liberar a memória, pois devemos ter certeza de liberar o conteúdo do ponteiro sem mais utilizá-lo.

Lembrando que se você acha ruim que seu browser/navegador, ou algum outro programa, consuma muita memória, aqui está o culpado… avise os programadores deste produto para lembrarem do free().

image

Mais um cuidado na alocação de memória: verificar se a mesma foi alocada corretamente! Como? verificando se o ponteiro não é nulo.

Vejamos mais um exemplo que explora os conceitos já citado:

#include <conio.h>
#include <stdio.h>
#include <stdlib.h>

void main()
{
    int *numero = (int *)malloc(2 + 2); 

    if(numero != NULL)
        *numero = 10;
    else
        printf("\n erro ao alocar memoria");

    printf("\n endereco de memoria %x", numero);
    printf("\n valor dentro do endereco de memoria %i", *numero);

    free(numero);

    getch();
}

image

Reparem que eu aloquei 4 bytes de memória (somando 2 mais 2), sem usar o sizeof(). Além disso verifiquei se o ponteiro não é nulo, para garantir que a memória foi alocada.

E no final liberei a memória utilizada… Logicamente.

Espero que tenham gostado. Até mais… E aloquem isso em suas memórias :)

0 comentários: