Ir para o conteúdo

Memória Dinâmica

Introdução

Imagina que queremos receber uma string do utilizador e a seguir copiar essa mesma string para outras, para fazermos algumas alterações sem alterar a string original. Uns dos passos lógicos é declarar 2 strings com tamanho suficiente para poder guardar a nossa string.Mas com isso levanta se uma questão. Não vamos desperdiçar memória se a string previamente reservada não fosse totalmente ocupada? As repostas está na memória dinâmica. A memória dinâmica permite-nos alocar bytes em memória em qualquer parte do nosso programa, assim possibilitando que nos já saibamos quantos bytes de memória essa string vai ocupar para assim não desperdiçarmos memória.

Nota: Todas as funções descritas aqui tem o prototipo disponível no header stdlib.h.

malloc

Aloca o número de bytes indicado pelo programador. A função retorna void * o que quiser dizer que pode alocar elementos para todos os tipos de dados, em caso de erro devolve NULL.

 void *malloc(size_t n_Bytes)

Onde:

  • size_t: significa unsigned int
  • n_Bytes: é o número de bytes que queremos alocar em memória
#include<stdio.h>
#include<string.h>
#include<stdlib.h> /* Precisamos desta biblioteca para acessar as funçoes de alocaçao de memoria*/

int main(void)
{
    char s[1000]; 
    char *ptr; /* Precisamos de um ponteiros */

    printf("Introduza a sua string:"); fgets(s,1000,stdin);

    if((ptr = malloc (strlen(s)+1))==NULL) /* Alocaçao do novo vector de caracteres */
        {
            printf("Nao foi possivel alocar a memoria");
            exit(1); 
        }

     strcpy(ptr,s); /* Copia a string que o utilizador inseriu para a nova */

     /* Vamos testar se correu todo bem */
     printf("String do utilizador:%s",s);
     printf("Nova String:%s",ptr);
     free(ptr); /* Liberta a memoria */

     return 0;
} 

Explicação: Basicamente o programa recebe uma string, e depois criamos uma nova string, mas agora com o número exacto de bytes que a string necessita para assim não haver desperdício de memória.

calloc

Aloca o número indicado pelo programador, onde o tipo também é passado como parâmetro. Ainda inicializa os novos espaços de memória a 0. A função devolve NULL em caso de erro.

 void *calloc(size_t num, size_t size)

Onde:

  • size_t: significa unsigned int
  • num: número de elementos que queremos criar
  • size: tamanho de cada elemento
#include <stdio.h>
#include <stdlib.h>

int main (void)
{
    char x;
    char *ptr;

    ptr = calloc (10,sizeof(char)); /* Alocaçao de 10 espaços de memoria do tipo char */

    if(ptr==NULL)
           {
                printf("Erro na Alocaçao!\n");
                exit(1);
           }

    free (ptr);
    return 0;
}

realloc

Esta função basicamente altera o espaço que foi atribuído à partida. A função retorna NULL em caso de erro.

 void *realloc(void *ptr, size_t new_size)
#include<stdlib.h>
#include<stdio.h>
#include<string.h>

int main(void)
{
    char *ptr;

    ptr = malloc(10)

    char *temp;    
    temp = realloc(ptr, 1000); /* Se o realloc funcionou,
                               ** temp aponta para uma área com 1000 bytes
                               ** e o valor de ptr não é relevante.
                               *  Se o realloc não funcionou
                               ** temp aponta para NULL
                               ** e ptr aponta para a área original, que pode ser libertada */
    if (temp != NULL) {
        ptr = temp;
    }

    /* Resto do código */

    free(ptr);
    return 0;
}

Nota: guardar o endereço da nova área no ponteiro que tem o endereço da área antiga.

ptr = realloc(ptr, 1000);

Dá origem, em caso de erro do malloc(), a que se perca a referência ao bloco original e consequentemente haja uma "memory leak" no programa.

free

Normalmente quando um programa termina a sua execução toda a memória gasta nesse programa é libertada, mas é bom habito de programação sermos nós a libertar essa memória. A função free() serve para isso mesmo.

 void free(void *ptr) 
free(ptr); /* ptr neste caso é o ponteiro para aquilo que criaram */