LPG - I: Alocao Dinmica de Memria - Ponteiros Prof. Flavio Marcello Strelow flavio@sbs.udesc.br PROGRAMA REA LIVRE Memria Disponvel no Computador Cdigo executvel: - instrues (compilador) - armazenamento do dados (estrutura dos dados) Memria livre, gerenciada pelo sistema operacional Alocao de Memria - Esttica Esttica Quantidade total de memria utilizada pelos dados previamente conhecida e definida de modo imutvel, no prprio cdigo-fonte do programa. Durante toda a execuo, a quantidade de memria utilizada pelo programa no varia. Lista de variveis declaradas. Alocao de Memria - Esttica Implementao simples: vetores (array) Vantagem: acesso indexado (v i )- todos os elementos da estrutura so igualmente acessveis Desvantagens: tamanho fixo (#define TAM 1000) tempo de compilao alocados em memria de forma esttica Alocao de Memria - Esttica Ao se determinar o mximo de elementos que o vetor ir conter, pode-se ocorrer um dos seguintes casos: Subdimensionamento: haver mais elementos a serem armazenados do que o vetor capaz de conter; Superdimensionamento: na maior parte do tempo, somente uma pequena poro do vetor ser realmente utilizada. Alocao de Memria - Dinmica Dinmica Quanto o programa capaz de criar novas variveis enquanto est sendo executado. Alocao de memria para componentes individuais no instante em que eles comeam a existir durante a execuo do programa. Alocao Esttica x Alocao Dinmica Alocao Dinmica Implementao eficiente: ponteiros ou apontadores Vantagens: tamanho varivel tempo de execuo alocados em memria de forma dinmica Desvantagem, ou restrio: capacidade da memria, acesso seqencial Alocao de Memria - Ponteiros No padro C ANSI que define as funes para a alocao dinmica (alocar e liberar blocos de memria em tempo de execuo) esto disponveis na biblioteca stdlib.h. malloc: alocar memria. free: liberar reas da memria ocupadas. Precisaremos tambem do: sizeof: retorna o tamanho de uma varivel.
Retorna o nmero de bytes necessrios para armazenar um objeto na memria, ou seja, saber o tamanho de tipos . O objeto pode ser um vetor, estrutura(struct) ou uma expresso como 5+9 ou 2.5*3. Alocao de Memria - malloc malloc void* malloc(tamanho_a_alocar);
Recebe o nmero de bytes a alocar. Retorna um apontador void para a base da regio contgua alocada na memria ou NULL se no for possvel aloc-la. responsabilidade do programador liberar a memria alocada dinamicamente com free. Produz erros estranhos quando usada para liberar um espao que j foi liberado.
Alocao de Memria - Exemplos Alocao de memria para um inteiro: int *p = malloc( 3 * sizeof(int));
Alocao de memria para um array de n reais: float *p = malloc(n * sizeof(float)); Lixo 10 Lixo 1FFA Representao Interna da Varivel do Tipo Ponteiro: void main() { int *p;
p = (int *) malloc(sizeof(int));
*p = 10; ... free(p); } memria usada pelo programa p: endereo 1FFA memria livre no sistema aloca a varivel estaticamente aloca a varivel dinamicamente I II III IV Lixo memria usada pelo programa p: memria livre no sistema Entendendo o cdigo:
I - int *p; A varivel p um ponteiro para um nmero inteiro, ou seja, aponta para um endereo de memria que ser alocado para armazenar um nmero inteiro (2 bytes)
II - p = (int *) malloc(sizeof(int)); Solicita ao sistema operacional 2 bytes da memria livre e o endereo do espao alocado colocado na varivel ponteiro p
III - *p = 10; No endereo apontado por p armazena o nmero inteiro 10
IV - free(p); Libera o espao de memria ocupado cujo endereo est em p (devolve o recurso ao sistema operacional) Exemplo Faa um programa para ler 10 nmeros reais e armazene em um vetor alocado dinamicamente. Depois, imprima os elementos lidos. Exemplo #include <stdio.h> #include <conio.h> #include <stdlib.h> #define TAM 10 int main() { int *pti, i; pti= (int *) malloc(sizeof(int) * TAM); if (pti == NULL) { /* verifica alocao, (poderia ser if(!pti)) */ printf("Erro ao alocar memria!\n"); return 1; /* sai do programa */ } for (i=0; i<TAM; i++) { printf("Digite um numero inteiro: "); scanf("%d", &pti[i]); /* l e armazena no vetor de endereos */ } /* Impressao do ponteiro */ for (i=0; i<TAM; i++) printf("%d", pti[i]); free(pti); // libera memoria. return 0; } LPG-I Flavio Marcello
Alocao de Ponteiros Exerccios Faa um programa que aloque uma string de 30 caracteres, armazene uma palavra digitada pelo usurio nesta string, imprima na tela e, depois de imprimido, desaloque esta string. Faa um programa que leia 5 strings e armazene em uma matriz de strings. Cada string deve ter seu espao alocado dinamicamente (considere strings de no mximo 20 caracteres na leitura). 3) Faa um programa que aloque uma string de 30 caracteres, armazene uma palavra digitada pelo usurio nesta string, imprima na tela e, depois de imprimido, desaloque esta string. #include <stdio.h> #include <stdlib.h> main() { char *string;
/* alocar a string de 30 caracteres */ string= (char *) malloc(sizeof(char) * 30);
if (!string) /* se alocao falhou (se string for igual a NULL) */ { printf("Erro ao alocar memria!\n"); return 1; /* sai do programa */ }
printf("Digite uma palavra: "); fgets(string, 30, stdin);
/*4) Faa um programa que leia 5 strings e armazene em uma matriz de strings. Cada string deve ter seu espao alocado dinamicamente (considere strings de no mximo 20 caracteres). */ #include <stdio.h> #include <stdlib.h> main() { char *mat[5]; int i; for (i=0; i<5; i++) { /* aloca espao para as strings */ mat[i]= (char *) malloc(sizeof(char) * 20); if (!mat[i]) { printf("Falha na alocao de memria!\n"); return 1; } printf("Digite uma palavra: "); fgets(mat[i], 20, stdin); }
/* imprime as strings */ for (i=0; i<5; i++) { puts(mat[i]); free(mat[i]); /* desaloca a string */ } return 0;
/* OBS: Quando um dado alocado dinamicamente, importante desaloc-lo antes de encerrar o programa. Se isso no for feito, a varivel continuar ocupando espao desnecessariamente aps o trmino da execuo do programa. Tambm importante testar se ocorreu algum erro na alocao, para trat-lo, se houver. */ }