Você está na página 1de 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

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

144

104

O acesso a cada elemento do vetor feito


atravs de uma indexao da varivel v .

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.

Você também pode gostar