Ferramentas de Usuário

Ferramentas de Site


dev_geral:c:memoria_dinamica

Memória Dinâmica

Introduçao

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 memoria se a string previamente reservada não fosse totalmente ocupada? A repostas esta na Memoria 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 memoria essa string vai ocupar para assim não desperdiçar mos memoria

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

malloc

Aloca o numero 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 numero de bytes que queremos alocar em memoria

#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 um string,e depois criamos uma nova string mas agora com o numero exacto de bytes que a string necessita para assim não haver desperdício de memoria

calloc

Aloca o numero indicado pelo programador,onde o tipo também é passado como paramento.Ainda inicializa os novos espaços de memoria a 0. A função recebe NULL em caso de erro.

 void *calloc(size_t num, size_t size)

Onde: size_t : significa unsigned int. num : Numero de elementos que queremos criar. size : Com que dimensoes queremos criar.

#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 a 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 memoria gasta nesse programa é libertada, mas é bom habito de programação sermos nos a libertar esse memoria.A função free serve para isso mesmo.

 void free(void *ptr) 
/* Codigo */
free(ptr); /* ptr neste caso é o ponteiro para aquilo que criaram */
dev_geral/c/memoria_dinamica.txt · Última modificação em: 2018/05/14 21:37 (edição externa)