Estrutura de Dados Alocação Dinâmica de Memória Professor Mário Dantas Contribuição: Professor Marcelo Douglas Alocação Dinâmica de Memória • Ponteiros fornecem o suporte necessário para o poderoso sistema de alocação dinâmica. • Alocação dinâmica é o meio pelo qual um programa pode obter memória enquanto está em execução. • Nenhuma variável pode ser acrescentada em um programa em tempo de execução. Porém haverá momentos em que um programa precisará usar quantidades de armazenamento variáveis. Alocação Dinâmica de Memória • Por exemplo, um processador de texto ou um banco de dados aproveita toda a RAM de um sistema. Porém, como a quantidade de RAM varia entre computadores esses programas não podem usar variáveis normais. • Em vez disso, esses e outros programas alocam memória, conforme necessário, usando as funções de alocação de memória. Alocação Dinâmica de Memória • A memória alocada pelas funções de alocação dinâmica é obtida do heap – a região de memória livre do seu computador. • Embora o tamanho do heap seja desconhecido, ele geralmente contém uma quantidade razoavelmente grande de memória livre. Alocação Dinâmica de Memória • No padrão C ANSI existem 4 funções para alocações dinâmica pertencentes a biblioteca stdlib.h. São elas malloc(), calloc(), realloc() e free(). Sendo que as mais utilizadas são as funções malloc() e free(). malloc() aloca memória free() libera memória Alocação Dinâmica de Memória • A alocação dinâmica é muito utilizada em problemas de estrutura de dados como por exemplo, listas encadeadas, pilhas, filas, arvores binárias e grafos. malloc() • A sintaxe da função malloc() é dada por: void *malloc(size_t numero_de_bytes); • numero_de_bytes é o número de bytes da memória que você quer alocar. • O tipo size_t é definido em stdlib.h como sendo um inteiro sem sinal. • O interessante é que esta função retorna um ponteiro do tipo void podendo assim ser atribuído a qualquer tipo de ponteiro. malloc() • O fragmento de código mostrado abaixo aloca 1000 bytes de memória: • Em alguns compiladores o código acima retornará um erro de conversão de tipo: malloc() • Para garantir portabilidade é interessante então efetuar o cast para o tipo de ponteiro que você deseja: • Após a atribuição, p aponta para o primeiro dos 1000 bytes de memória livre. malloc() • O próximo exemplo aloca espaço para 50 inteiros. • Observe o uso de sizeof para assegurar a portabilidade: malloc() • Como o heap não é infinito, sempre que alocar memória, você deve testar o valor devolvido por malloc(), antes de usar o ponteiro, para estar certo de que não é nulo. • Usar um ponteiro nulo quase certamente travará o computador. free() • A função free() é o oposto de malloc(), visto que ela devolve memória previamente alocada ao sistema. • Uma vez que a memória tenha sido liberada, ela pode ser realocada por uma nova chamada a malloc(). void free(void *pont) • Aqui, pont é um ponteiro para a memória alocada anteriormente por malloc(). É muito importante que você nunca use free() com um argumento inválido, isso destruiria a lista de memória livre. Estrutura de Dados Exemplos de Alocação Dinâmica de Memória