Sunteți pe pagina 1din 29

Universidade de So Paulo So Carlos Instituto de Cincias Matemticas e de Computao

Alocao Dinmica em C

Profa Rosana Braga Adaptado de material preparado pela profa Silvana Maria Affonso de Lara 1 semestre de 2010
1

Roteiro da Aula

Alocao Dinmica de Memria Vetores e alocao dinmica Alocao da memria principal Funes para alocar e liberar memria Alocao dinmica de matrizes

Vetores e alocao dinmica

A forma mais simples de estruturarmos um conjunto de dados por meio de vetores Definimos um vetor em C da seguinte forma: int v[10]; Esta declarao diz que v um vetor de inteiros dimensionado com 10 elementos, isto , reservamos um espao de memria contnuo para armazenar 10 valores inteiros. Assim, se cada int ocupa 4 bytes, a declarao reserva um espao de memria de 40 bytes
3

Vetores e alocao dinmica

O acesso a cada elemento do vetor feito atravs de uma indexao da varivel v .

144

Em C, a indexao de um vetor varia de zero a n-1, onde n representa a dimenso do vetor. v[0] acessa o primeiro elemento de v v[1] acessa o segundo elemento de v ... Mas v[10] invade a memria

104

v
4

Vetores e alocao dinmica


float v[10]; int i; /* leitura dos valores */ for (i = 0; i < 10; i++) scanf("%f", &v[i] );

Observe que passamos para scanf o endereo de cada elemento do vetor ( &v[i] ), pois desejamos que os valores capturados sejam armazenados nos elementos do vetor.

Se v[i] representa o (i+1)-simo elemento do vetor, &v[i] representa o endereo de memria onde esse elemento est armazenado Existe uma associao entre vetores e ponteiros, pois a varivel v , que representa o vetor, uma constante que armazena o endereo inicial do vetor, isto , v , sem indexao, aponta para o primeiro elemento do vetor.
5

Vetores e alocao dinmica


num vetor temos as seguintes equivalncias: v + 0 aponta para o primeiro elemento do vetor v + 1 aponta para o segundo elemento do vetor v + 9 aponta para o ltimo elemento do vetor

Portanto, escrever &v[i] equivalente a escrever (v+i) De maneira anloga, escrever v[i] equivalente a escrever

*(v+i) ( lgico que a forma indexada mais clara e adequada)


Note que o uso da aritmtica de ponteiros aqui perfeitamente

vlido, pois os elementos dos vetores so armazenados de forma contnua na memria


6

Vetores e alocao dinmica

Passar um vetor para uma funo consiste em passar o endereo da primeira posio do vetor. Se passarmos um valor de endereo, a funo chamada deve ter um parmetro do tipo ponteiro para armazenar este valor. Assim, se passarmos para uma funo um vetor de int , devemos ter um parmetro do tipo int* , capaz de armazenar endereos de inteiros Salientamos que a expresso passar um vetor para uma funo deve ser interpretada como passar o endereo inicial do vetor. Os elementos do vetor no so copiados para a funo, o argumento copiado apenas o endereo do primeiro elemento.

Vetores e alocao dinmica


/* Incrementa elementos de um vetor */

#include <stdio.h> void incr_vetor ( int n, int *v ) { int i; for (i = 0; i < n; i++) A sada do programa 2 4 6 , pois os elementos do vetor sero v[i]++; incrementados dentro da funo. } int main ( void ) { int a[ ] = {1, 3, 5}; incr_vetor(3, a); printf("%d %d %d \n", a[0], a[1], a[2]); return 0; }
8

Alocar memria dinamicamente


a linguagem C oferece meios de requisitarmos espaos de memria em tempo de execuo. Uso da memria (1) uso de variveis globais (e estticas). O espao reservado para uma varivel global existe enquanto o programa estiver sendo executado. (2) uso de variveis locais. Neste caso, o espao existe apenas enquanto a funo que declarou a varivel est sendo executada, sendo liberado para outros usos quando a execuo da funo termina. Assim, a funo que chama no pode fazer referncia ao espao local da funo chamada. (3) reservar memria requisitando ao sistema, em tempo de execuo, um espao de um determinado tamanho.

Alocar memria dinamicamente

O espao alocado dinamicamente permanece reservado at que explicitamente seja liberado pelo programa. Por isso, podemos alocar dinamicamente um espao de memria numa funo e acess-lo em outra. A partir do momento que liberarmos o espao, ele estar disponibilizado para outros usos e no podemos mais acess-lo. Se o programa no liberar um espao alocado, este ser automaticamente liberado quando a execuo do programa terminar.

10

Alocao da Memria Principal


Cdigo do Programa
Variveis Globais e Estticas Memria Alocada Dinamicamente

Memria Livre Pilha


11

Alocao da Memria Principal

Para executar um determinado programa, o S.O. carrega na memria o cdigo do programa, em linguagem de mquina. Alm disso, o S.O. reserva os espaos necessrios para armazenar as variveis globais (e estticas) do programa O restante da memria livre utilizado pelas variveis locais e pelas variveis alocadas dinamicamente.

12

Alocao da Memria Principal

Cada vez que uma funo chamada, o S.O. reserva o espao necessrio para as variveis locais da funo. Este espao pertence pilha de execuo e, quando a funo termina, liberado. A memria no ocupada pela pilha de execuo pode ser requisitada dinamicamente. Se a pilha tentar crescer mais do que o espao disponvel existente, dizemos que ela estourou e o programa abortado com erro.
13

Alocao Dinmica de Memria


As funes calloc e malloc permitem alocar blocos de memria em tempo de execuo
void * malloc(

size

); nmero de bytes alocados

/* retorna um ponteiro void para n bytes de memria no iniciados. Se no h memria disponvel malloc retorna NULL */
14

Alocao Dinmica de Memria


As funes calloc e malloc permitem alocar blocos de memria em tempo de execuo
void * calloc(n, size); /* calloc retorna um ponteiro para um array com n elementos de tamanho size cada um ou NULL se no houver memria disponvel. Os elementos so iniciados em zero */

o ponteiro retornado por malloc e calloc deve ser convertido para o tipo de ponteiro que invoca a funo
15

Alocao da Memria Principal


Exemplos Cdigo que aloca 1000 bytes de memria livre: char *p; p = malloc(1000); Cdigo que aloca espao para 50 inteiros: int *p; p = malloc(50*sizeof(int)); Obs.: O operador sizeof() retorna o nmero de bytes de um inteiro.

16

Funes para Alocar e Liberar memria


Funo bsica para alocar memria malloc int *vet; vet = malloc(10*4);
Aps esses comandos, se a alocao for bem

sucedida, vet armazenar o endereo inicial de uma rea contnua de memria suficiente para armazenar 10 valores inteiros.
Desta forma, consideramos que um inteiro ocupa 4

bytes. Para ficarmos independentes de compiladores e mquinas, usamos o operador sizeof( ) v = malloc(10*sizeof(int));
17

Funes para Alocar e Liberar memria


A funo malloc usada para alocar espao para armazenarmos valores de qualquer tipo. Por este motivo, malloc retorna um ponteiro genrico, para um tipo qualquer, representado por void* , que pode ser convertido automaticamente pela linguagem para o tipo apropriado na atribuio. No entanto, comum fazermos a converso explicitamente, utilizando o operador de molde de tipo (cast). Ento: v = (int *) malloc(10*sizeof(int));
18

Funes para Alocar e Liberar memria


Se no houver espao livre suficiente para realizar a alocao, a funo retorna um endereo nulo (representado pelo
smbolo NULL , definido em stdlib.h).

Podemos tratar o erro na alocao do programa verificando o valor de retorno da funo malloc Ex: imprimindo mensagem e abortando o programa com a funo exit, tambm definida na stdlib.
Int * v; v = (int*) malloc(10*sizeof(int)); if (v==NULL) { printf("Memoria insuficiente.\n"); exit(1); /* aborta o programa e retorna 1 para o sist. operacional */ }
19

Liberao de Memria
int *pi = (int *) malloc (sizeof(int)); /* aloca espao para um inteiro */ int *ai = (int *) calloc (n, sizeof(int)); /* aloca espao para um array de n inteiros */

toda memria no mais utilizada deve ser liberada atravs da funo free():

free(ai); /* libera todo o array */ free(pi); /* libera o inteiro alocado */

20

Exerccio 1

Escreva um programa em C que solicita ao usurio um nmero n e ento l um vetor de n notas e calcula a mdia aritmtica.

Usar alocao dinmica do vetor Liberar a memria ao final No limitar o uso de memria

21

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, o que denominado indireo mltipla A indireo mltipla pode ser levada a qualquer dimenso desejada.

22

Alocao dinmica de matrizes

** p0

** p2+1 ** p3+3

Alocao dinmica de matrizes

Cada linha da matriz representada por um vetor independente. A matriz ento representada por um vetor de vetores, ou vetor de ponteiros, no qual cada elemento armazena o endereo do primeiro elemento de cada linha

Alocao dinmica de matrizes


#include <stdio.h> #include <stdlib.h> float **Alocar_matriz_real (int m, int n) { float **v; /* ponteiro para a matriz */ int i; /* variavel auxiliar */ if (m < 1 || n < 1) { /* verifica parametros recebidos */ printf ("** Erro: Parametro invalido **\n"); return (NULL); }
/* aloca as linhas da matriz */

v = (float **) calloc (m, sizeof(float *)); if (v == NULL) { printf ("** Erro: Memoria Insuficiente **"); return (NULL); }
25

Alocao dinmica de matrizes


/* aloca as colunas da matriz */

for ( i = 0; i < m; i++ ) { v[i] = (float*) calloc (n, sizeof(float)); if (v[i] == NULL) { printf ("** Erro: Memoria Insuficiente **"); return (NULL); } } return (v); /* retorna o ponteiro para a matriz */ }

26

Alocao dinmica de matrizes


float **Liberar_matriz_real (int m, int n, float **v) { int i; /* variavel auxiliar */ if (v == NULL) return (NULL); if (m < 1 || n < 1) { /* verifica parametros recebidos */ printf ("** Erro: Parametro invalido **\n"); return (v); } for (i = 0; i < m; i++) free (v[i]); /* libera as linhas da matriz */ free (v); /* libera a matriz */ return (NULL); /* retorna um ponteiro nulo */ }
27

Alocao dinmica de matrizes


void main (void) { float **mat; /* matriz a ser alocada */ int l, c; /* numero de linhas e colunas da matriz */
... /* outros comandos, inclusive inicializacao para l e c */

mat = Alocar_matriz_real (l, c);


... /* outros comandos utilizando mat[][] normalmente */

mat = Liberar_matriz_real (l, c, mat); ... }

28

Exerccio 2
Modificar o programa de alocao dinmica de matrizes dado anteriormente (slides 25 a 28) para que leia aloque dinamicamente duas matrizes de 3 por 4, leia seus elementos e imprima a matriz soma.

S-ar putea să vă placă și