Você está na página 1de 19

Alocao Dinmica

Introduo A funo malloc() A funo calloc() A funo realloc() A funo free() Alocao Dinmica de Vetores Alocao Dinmica de Matrizes

Alocao Dinmica
Introduo
A alocao dinmica permite ao programador alocar memria para variveis quando o programa est sendo executado. Assim, poderemos definir, por exemplo, um vetor ou uma matriz cujo tamanho descobriremos em tempo de execuo. O padro C ANSI define apenas 4 funes para o sistema de alocao dinmica, disponveis na biblioteca stdlib.h: malloc() calloc() realloc() free()

No entanto, existem diversas outras funes que so amplamente utilizadas, mas dependentes do ambiente e compilador.

Alocao Dinmica
A funo malloc()
A funo malloc() serve para alocar memria e tem o seguinte prottipo: void *malloc (unsigned int num); A funo toma o nmero de bytes que queremos alocar (num), aloca na memria e retorna um ponteiro void * para o primeiro byte alocado. O ponteiro void * deve ser atribudo a qualquer tipo de ponteiro. Se no houver memria suficiente para alocar a memria requisitada a funo malloc() retorna um ponteiro nulo (NULL).

Alocao Dinmica
A funo malloc()
Exemplo:

#include <stdlib.h> /* Para usar malloc() */ #include <stdio.h> int main (void) { int *p, a, i; /* ... Determinar o valor de a em algum lugar... */ p = (int *) malloc(a*sizeof(int)); /* Aloca a inteiros p pode agora ser tratado como um vetor com a posies */ if (!p) { /* ou, if (p == NULL) */ printf("** Erro: Memria Insuficiente **\n); exit; } for (i=0; i<a ; i++) p[i] = i*i; /* p pode ser tratado como um vetor com a posies */ /* ... */ return 0; }

Alocao Dinmica
A funo malloc()
No exemplo anterior, alocada memria suficiente para se armazenar a nmeros inteiros. A funo sizeof() retorna o nmero de bytes de um inteiro. Ele til para se saber o tamanho de tipos. O ponteiro void* que malloc() retorna convertido para um int * pelo cast e atribudo a p. A declarao seguinte testa se a operao foi bem sucedida. Se no tiver sido, p ter um valor nulo, o que far com que !p seja verdadeiro. Se a operao tiver sido bem sucedida, podemos usar o vetor de inteiros alocados normalmente, por exemplo, indexando-o: p[0] at p[(a-1)].

Alocao Dinmica
A funo calloc()
A funo calloc() tambm serve para alocar memria, mas possui um prottipo um pouco diferente: void *calloc(unsigned int num, unsigned int size);

A funo aloca uma quantidade de memria igual a num * size, isto , aloca memria suficiente para um vetor de num objetos de tamanho size.
Retorna um ponteiro void * para o primeiro byte alocado. O ponteiro void * pode ser atribudo a qualquer tipo de ponteiro. Se no houver memria suficiente para alocar a memria requisitada a funo calloc() retorna um ponteiro nulo. Em relao a malloc(), calloc() tem uma diferena (alm do fato de ter prottipo diferente): calloc() inicializa o espao alocado com 0s.

Alocao Dinmica
A funo calloc()
Exemplo:

#include <stdlib.h> /* Para usar calloc() */ #include <stdio.h> int main (void) { int *p, a, i; /* ... Determinar o valor de a em algum lugar ... */ p = (int *) calloc(a, sizeof(int)); /* Aloca a inteiros. p pode agora ser tratado como um vetor com a posies */ if (!p) { // ou, if (p == NULL) printf("** Erro: Memria Insuficiente **\n); exit; } for (i=0; i<a ; i++) p[i] = i*i; /* p pode ser tratado como um vetor com a posies */ /* ... */ return 0; }

Alocao Dinmica
A funo calloc()
No exemplo anterior, alocada memria suficiente para se colocar a nmeros inteiros. O operador sizeof() retorna o nmero de bytes de um inteiro. Ele til para se saber o tamanho de tipos. O ponteiro void * que calloc() retorna convertido para um int * pelo cast e atribudo a p. A declarao seguinte testa se a operao foi bem sucedida. Se no tiver sido, p ter um valor nulo, o que far com que !p retorne verdadeiro. Se a operao tiver sido bem sucedida, podemos usar o vetor de inteiros alocados normalmente, por exemplo, indexando-o: p[0] at p[(a-1)].

Alocao Dinmica
A funo realloc()
A funo realloc() serve para realocar memria e tem o seguinte prottipo: void *realloc(void *ptr, unsigned int num); A funo modifica o tamanho da memria 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 contedo do bloco antigo copiado no novo bloco, e nenhuma informao perdida. Se ptr for nulo, aloca num bytes e devolve um ponteiro; se num zero, a memria apontada por ptr liberada. Se no houver memria suficiente para a alocao, um ponteiro nulo devolvido e o bloco original deixado inalterado.

Alocao Dinmica
A funo realloc()
Exemplo:

#include <stdlib.h> /* Para usar malloc() e realloc() */ #include <stdio.h> int main (void) { int *p, a = , i; /* ... Determinar o valor de a em algum lugar. Exemplo, a = 30; */ if(p= (int *) malloc(a*sizeof(int))==NULL); { printf("** Erro: Memria Insuficiente **\n); exit; } for (i=0; i<a ; i++) p[i] = i*i; a = 100; /* o valor de a mudou... */ if(p= (int *) realloc(p, a*sizeof(int))==NULL); { printf("** Erro: Memria Insuficiente **\n); exit; } for (i=0; i<a ; i++) p[i] = a*i*(i-6); return 0; }

Alocao Dinmica
A funo free()
Quando alocamos memria dinamicamente necessrio que ns a liberemos quando ela no for mais necessria. Para isto existe a funo free() cujo prottipo : void free (void *ptr); Basta ento passar para free() o ponteiro que aponta para o incio da memria alocada. Mas voc pode se perguntar: como que o programa vai saber quantos bytes devem ser liberados? Ele sabe pois quando voc alocou a memria, ele guardou o nmero de bytes alocados numa "tabela de alocao" interna.

Alocao Dinmica
Alocao Dinmica de Vetores
float *v; int c;

c v
float* float float

...

float

Alocao Dinmica
Alocao Dinmica de Vetores.
Exemplo:
#include <stdlib.h> /* Para usar calloc() e free() */ #include <stdio.h> int main(void){ float *v; /* ponteiro para o vetor */ int c; /* dimenso do vetor */ printf("Colunas: "); scanf("%d", &c); /* aloca o vetor */ if(v = (float *) calloc (c, sizeof(float)) == NULL) { printf ("** Erro: Memria Insuficiente **"); exit(1); } /* Utilizao do ponteiro como vetor */ free(v); /* libera o vetor */ return 0; }

Alocao Dinmica
Alocao Dinmica de Matrizes
A alocao dinmica de memria para matrizes realizada da mesma forma que para vetores, com a diferena que teremos um ponteiro apontando para outro ponteiro que aponta para o valor final, ou seja um ponteiro para ponteiro, o que denominado indireo mltipla. A indireo mltipla pode ser levada a qualquer dimenso desejada, mas raramente necessrio mais de um ponteiro para um ponteiro. A estrutura de dados utilizada neste exemplo composta por um vetor de ponteiros (correspondendo ao primeiro ndice da matriz), sendo que cada ponteiro aponta para o incio de uma linha da matriz. Em cada linha existe um vetor alocado dinamicamente, como descrito anteriormente (compondo o segundo ndice da matriz).

Alocao Dinmica
Alocao Dinmica de Matrizes
float **m; int l, c;

l m
float** float* float*

...

float* float float

c
float float

...

float float

...
. . .

float

float

...

float

Alocao Dinmica
Alocao Dinmica de Matrizes
Exemplo:
int main(void){ float **m; /* ponteiro para a matriz */ int l, c; /* dimenses da matriz */ int i, j; /* variveis auxiliares */ /* ... */ printf("Linhas: "); scanf("%d", &l); printf("Colunas: "); scanf("%d", &c);

if(l < 1 || c < 1) { /* verifica parmetros recebidos */ printf("** Erro: Parmetro invalido **\n"); exit(1); }
/* aloca as linhas da matriz - um vetor de l ponteiros para float */ if((m = (float **) calloc(l, sizeof(float *))) == NULL) { printf("** Erro: Memria Insuficiente **\n"); exit(1); }

Alocao Dinmica
Alocao Dinmica de Matrizes
Exemplo:
/* aloca as colunas de cada linha da matriz */ for(i = 0; i < l; i++) { /* l vetores de n floats */ if((*(m + i) = (float *) calloc(c, sizeof(float))) == NULL) { printf("** Erro: Memria Insuficiente **\n"); exit(1); } } /* inicializa os elementos da matriz */ for (i = 0; i < l; i++) for (j = 0; j < c; j++) *(*(m + i) + j) = (float) i + j; /* exibe os elementos da matriz */ for(i = 0; i < l; i++){ for(j = 0; j < c; j++) printf("%10.2f ", *(*(m + i) + j)); printf("\n"); }

Alocao Dinmica
Alocao Dinmica de Matrizes
Exemplo:
/* libera a memria para as colunas de cada linha */ for(i = 0; i < l; i++) free(*(m + i)); /* libera o vetor de ponteiros para floats */ free(m); return 0; }

Alocao Dinmica
Alocao Dinmica Exerccio.
Faa um programa que multiplique duas matrizes. O programa dever estar estruturado de maneira que: o usurio fornea as dimenses das matrizes (teste se as dimenses so compatveis, isto , se as matrizes podem ser multiplicadas); as matrizes sejam alocadas dinamicamente; as matrizes sejam lidas pelo teclado; as matrizes sejam, ento, multiplicadas; a matriz resultante seja apresentada em tela OBS:

a) Faa, tambm, alocao dinmica da matriz resultante. b) Caso algum no conhea o procedimento para a multiplicao de matrizes, segue aqui alguma orientao. Suponha as matrizes a[m][n] e b[n][t]. Cada elemento [i][j] da matriz c resultante da soma dos produtos da linha i de a pela coluna j de b, resultando na matriz c[m][t].

Você também pode gostar