Por: Eduardo Casavella
Alocação Estática
Na alocação estática de memória, os tipos de dados tem tamanho predefinido. Neste caso, o compilador vai alocar de forma automática o espaço de memória necessário. Sendo assim, dizemos que a alocação estática é feita em tempo de compilação. Este tipo de alocação tende a desperdiçar recursos, já que nem sempre é possível determinar previamente qual é o espaço necessário para armazenar as informações. Quando não se conhece o espaço total necessário, a tendência é o programador exagerar pois é melhor superdimensionar do que faltar espaço.
Alocação Dinâmica
Na alocação dinâmica podemos alocar espaços durante a execução de um programa, ou seja, a alocação dinâmica é feita em tempo de execução. Isto é bem interessante do ponto de vista do programador, pois permite que o espaço em memória seja alocado apenas quando necessário. Além disso, a alocação dinâmica permite aumentar ou até diminuir a quantidade de memória alocada.
sizeof
A função sizeof determina o número de bytes para um determinado tipo de dados.
É interessante notar que o número de bytes reservados pode variar de acordo com o compilador utilizado.
Exemplo:
x = sizeof(int); //retorna 4 no gcc
malloc
A função malloc aloca um espaço de memória e retorna um ponteiro do tipo void para o início do espaço de memória alocado.
free
A função free libera o espaço de memória alocado.
Exemplo: Vetor Dinâmico
Quando um programador define tipo e o número de elementos um vetor ele está utilizando alocação estática.
Uma alternativa interessante é declarar um vetor como ponteiro, a fim de utilizar alocação dinâmica. Para tanto devemos usar a função malloc. Porém, esta função necessita saber a quantidade de bytes que devem ser reservados. Para fazer esse cálculo usamos o comando sizeof.
Vejamos como implementar esses detalhes no exemplo prático abaixo:
#include <stdio.h> #include <stdlib.h> //necessário para usar as funções malloc() e free() #include <conio.h> int main(void) { float *v; //definindo o ponteiro v int i, num_componentes; printf("Informe o numero de componentes do vetor\n"); scanf("%d", &num_componentes); /* ------------- Alocando dinamicamente o espaço necessário ------------- 1 - Calcular o número de bytes necessários primeiramente multiplicamos o número de componentes do vetor pela quantidade de bytes que é dada pelo comando sizeof, portanto temos: num_componentes * sizeof(float) 2 - Reservar a quantidade de memória usamos malloc para reservar essa quantidade de memória, então temos: malloc(num_componentes * sizeof(float)) 3 - Converter o ponteiro para o tipo de dados desejado como a função malloc retorna um ponteiro do tipo void, precisamos converter esse ponteiro para o tipo da nossa variável, no caso float, por isso usamos o comando de conversão explicita: (float *) 4 - juntando tudo e atribuindo em v temos o comando abaixo: */ v = (float *) malloc(num_componentes * sizeof(float)); //Armazenando os dados em um vetor for (i = 0; i < num_componentes; i++) { printf("\nDigite o valor para a posicao %d do vetor: ", i+1); scanf("%f",&v[i]); } // ------ Percorrendo o vetor e imprimindo os valores ---------- printf("\n*********** Valores do vetor dinamico ************\n\n"); for (i = 0;i < num_componentes; i++) { printf("%.2f\n",v[i]); } //liberando o espaço de memória alocado free(v); getch(); return 0; }
Tela de execução
Alocação Dinâmica de Matriz em C
Para o exemplo a seguir vamos fazer a leitura dos valores da matriz usando um arquivo texto, portanto será necessário criar o arquivo denominado ArqMatrizes.txt com os valores conforme a figura a seguir:
Esse arquivo é composto pelas dimensões das matrizes: 3 6, ou seja 3 linhas e 6 colunas, e também pelos valores das duas matrizes com dimensão 3 x 6.
No código a seguir vamos alocar dinamicamente duas matrizes 3 X 6 e fazer a leitura dos valores do arquivo texto.
Em seguida vamos alocar dinamicamente uma terceira matriz que vai conter a soma dos valores das outras duas matrizes.
#include <stdio.h> #include <stdlib.h> //necessário para usar as funções malloc() e free() #include <stdlib.h> int main(void) { int i,j,n_linhas,n_colunas; //matrizes dinâmicas de duas dimensões portanto vamos necessitar um ponteiro para a linha //e outro ponteiro apontando para coluna int **matriz1,**matriz2,**matriz_soma; FILE *ptrArq; //Abrindo o arquivo ptrArq = fopen("ArqMatrizes.txt", "r"); //Verificando se a abertura do arquivo foi bem sucedida if (ptrArq == NULL) { printf("Erro ao abrir o arquivo!\n"); printf("Saindo do programa...\n"); system("pause"); exit(1);//abortando o programa } // Leitura das dimensões da matriz a partir dos valores do arquivo fscanf(ptrArq,"%d %d",&n_linhas,&n_colunas); // Alocar a memória necessária para as matrizes //----------------- Alocando a matriz1 --------------- // alocar a quantidade de linhas matriz1 = (int **)calloc(n_linhas,sizeof(int *)); for (i = 0; i < n_linhas; i++) { // alocar a quantidade de colunas de cada linha matriz1[i] = (int *)calloc(n_colunas,sizeof(int)); } //----------------- Alocando a matriz2 --------------- matriz2 = (int **)calloc(n_linhas,sizeof(int *)); for (i = 0; i < n_linhas; i++) { matriz2[i] = (int *)calloc(n_colunas,sizeof(int)); } // ------- Ler os valores para as matrizes a partir do arquivo texto ------ for (i = 0; i < n_linhas; i++) { for (j = 0; j < n_colunas; j++) { fscanf(ptrArq,"%d",&matriz1[i][j]);//ler um inteiro do arquivo e armazenar na matriz1 } } for (i = 0; i < n_linhas; i++) { for (j = 0; j < n_colunas; j++) { fscanf(ptrArq,"%d",&matriz2[i][j]);//ler um inteiro do arquivo e armazenar na matriz2 } } fclose(ptrArq);//Fechar o arquivo // --------------- Mostrar as matrizes lidas --------------------- printf("Matrizes lidas do arquivo:\n"); for (i = 0; i < n_linhas; i++) { for (j = 0; j < n_colunas; j++) { printf("%2d ",matriz1[i][j]); } printf(" "); //Espaçamento entre as duas matrizes for (j = 0; j < n_colunas; j++) { printf("%2d ",matriz2[i][j]); } printf("\n"); } // Alocar memoria para matriz soma matriz_soma = (int **)calloc(n_linhas,sizeof(int *)); for (i = 0; i < n_linhas; i++) { matriz_soma[i] = (int *)calloc(n_colunas,sizeof(int)); } // Calcular matriz soma for (i = 0; i < n_linhas; i++) { for (j = 0; j < n_colunas; j++) { matriz_soma[i][j] = matriz1[i][j] + matriz2[i][j]; } } // Mostrar matriz soma printf("\nMatriz soma:\n"); for (i = 0; i < n_linhas; i++) { for (j = 0; j < n_colunas; j++) { printf("%3d ",matriz_soma[i][j]); } printf("\n"); } //liberando a memória da matriz1 //para matrizes a liberação da memória ocorre na ordem inversa da alocação for (i=0; i < n_linhas; i++) { free (matriz1[i]) ; } free (matriz1) ; //liberando a memória da matriz2 for (i=0; i < n_linhas; i++) free (matriz2[i]) ; free (matriz2) ; //liberando a memória da matriz_soma for (i=0; i < n_linhas; i++) free (matriz_soma[i]) ; free (matriz_soma); printf("\n"); system("pause"); return 0; }
Até a próxima!
6 respostas a Alocação Dinâmica em C