Baixe o app para aproveitar ainda mais
Prévia do material em texto
Alocação Dinâmica de Memória Belo Horizonte, maço de 2012 Alocação Dinâmica de Memória • Pode-se alocar (reservar) blocos de bytes de memória dinamicamente durante a execução do programa (em tempo de execução). • As alocações de memórias são alocadas na parte da memória chamada de heap (monte). • Isto é feito, por exemplo, pela função malloc (memory allocation) da biblioteca padrão. void *malloc(size_t) • Protótipo encontrado em stdlib.h ou alloc.h • size_t é um tipo unsigned long int que se refere ao tamanho a ser alocado em bytes. • Retorna um endereço para um tipo void (sem tipo) quando se conseguiu alocar ou NULL se não consegui alocar a memória. void free(void *) • Serve para desalocar a memória alocada no heap. • TODA memória alocada DEVE ser desalocada (liberada). • Recebe como parâmetro o endereço a ser desalocado (liberado) do heap. Alocando um vetor de 35 caracteres char *m; m = (char *) malloc(35); if (!m) { /* m == NULL */ puts(“\n Erro de alocação\n”); exit(0); } . . . . . . free(m); O vetor de 35 caracteres alocado dinamicamente (em tempo de execução) e é alocado na área de heap. A variável ponteiro *m tem o endereço do 1º byte alocado no heap. Área de Pilha Área de Heap (Monte) Área de Dados Área de Código *m Alocando de um vetor de 20 inteiros int *m; m = (int *) malloc(sizeof(int) * 20); if (!m) { puts(“\n Erro de alocação\n”); exit(0); } . . . . . . free(m); Alocando uma matriz de 20x30 de double double*m; m = (double *) malloc(sizeof(double) * 20 * 30); if (!m) { puts(“\n Erro de alocação\n”); exit(0); } m[30*2+10] = 10.5; // posição [2][10] . . . . . . free(m); IMPORTANTE • A partir da alocação de memória para uma matriz qualquer, tem-se apenas o endereço do 1º byte. • A única forma de manipular a matriz é por intermédio de um índice unidimensional. • Usa-se a seguinte fórmula: – Total de colunas da matriz * linha + coluna. • ERRADO fazer: m[2][3] = 10.5; • CORRETO fazer: m[30*2+3] = 10.5; Bidimensional para Unidimensional 1 0 0 1 0 1 2 3 Total de colunas * linha + coluna [0][0] = [2*0+0] = [0] [0][1] = [2*0+1] = [1] [1][0] = [2*1+0] = [2] [1][0] = [2*1+1] = [3] Tem-se apenas o endereço do 1º byte Dada a Estrutura de Dados 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 0 1 2 3 4 Como alocá-la na memória??? int **m = (int **) malloc(sizeof(int **) * 5); if (!m) { puts("\n faltou memória . . . \n"); return 0; } for (int i = 0; i < 5; i++) m[i] = (int *) malloc(sizeof(int) * 3); for (int i = 0; i < 5; i++) for (int j = 0; j < 3; j++) m[i][j] = i; for (int i = 0; i < 5; i++) { for (int j = 0; j < 3; j++) printf("%i ",m[i][j]); printf("\n"); } for (int i = 0; i < 5; i++) if (m[i]) free((int *) m[i]); if (m) free(m); Alocar o vetor de ponteiros Verificar se alocou Alocar vetores Atribuir de valores Mostrar o conteúdo (valores) Desalocar memória 10 10 10 11 11 11 12 12 12 13 13 13 14 14 14 0 1 2 3 4 0 1 2 10 10 10 11 11 11 12 12 12 13 13 13 14 14 14 0 1 2 3 4 10 10 10 11 11 11 12 12 12 13 13 13 14 14 14 0 1 2 3 4 Sugestão: Apresente o código fonte para: Alocar esta estrutura dinamicamente. Preencher com os devidos valores. Desalocar (liberar a memória) alocada. • A programação com ponteiros requer muita atenção dos programadores para não gerar erros na sua manipulação. Problemas mais Comuns com Ponteiros • Baixa legibilidade. – A expressão p->cauda = q; por meio de uma simples inspeção não dá para saber qual estrutura de dados está sendo atualizada. Problemas mais Comuns com Ponteiros • Erro de violação do sistema de tipos. int i, j = 10; int *p = &j; /* p recebe o endereço de j */ p++; /* p não necessariamente tem o endereço de um inteiro */ i = *p + 5; /* valor IMPREVISÍVEL atribuído em i */ Problemas mais Comuns com Ponteiros • Objetos pendentes. int *p = (int *) malloc(10*sizeof(int)); int *q = (int *) malloc(5*sizeof(int)); p = q; /* a área apontada por p torna-se inacessível o endereço que p tinha torna-se perdido */ Problemas mais Comuns com Ponteiros • Referências pendentes. • Diz-se referência pendente por desalocação (liberação) explícita. int *p = (int *) malloc(10*sizeof(int)); int *q = p; free(p); /* q tem um endereço de uma área de memória que já foi desalocada (liberada) */
Compartilhar