Esta página é um pequeno resumo sobre alocação dinâmica de memória, ou seja, alocação que ocorre durante a execução de um programa.
A função malloc (abreviatura de memory allocation) da biblioteca padrão aloca um bloco de bytes consecutivos na memória do computador e devolve o endereço desse bloco. Eis um exemplo bobo que recebe um caracter e imprime o caracter seguinte da tabela ISO 8859-1:
char *ptr;
ptr = malloc (1);
scanf ("%c", ptr);
printf ("%c\n", *ptr + 1); /* não confunda com *(ptr+1) */
free (ptr);
Eis outro exemplo bobo, que calcula a soma de dois números:
int *ptr; int x; ptr = malloc (sizeof (int)); scanf ("%d %d", ptr, &x); *ptr = *ptr + x; printf ("%d\n", *ptr); free (ptr);
A expressão sizeof (int) dá o número de bytes de um int. No meu computador, esse número é 4.
A função malloc devolve um ponteiro "genérico" — ou seja, do tipo void * — para um bloco de bytes consecutivos. No exemplo acima, esse ponteiro é automaticamente convertido em ponteiro-para-int uma vez que a variável ptr é do tipo int *.
A função free libera a porção de memória alocada por malloc. O comando free (ptr) avisa o sistema de que o bloco de bytes apontado por ptr está livre. A próxima chamada de malloc poderá tomar posse desses bytes.
As funções malloc e free estão na biblioteca stdlib. Portanto, diga
#include <stdlib.h>
no início de qualquer programa que use malloc e free.
Se a memória do computador já estiver toda ocupada, malloc não consegue alocar mais espaço e devolve NULL. Convém verificar essa possibilidade antes de prosseguir:
ptr = malloc (sizeof (int)); if (ptr == NULL) { printf ("Socorro! malloc devolveu NULL!\n"); exit (EXIT_FAILURE); }
A codificação freqüente e repetida desse teste é cansativa para o programador e desvia a atenção do leitor. Por isso, vamos usar a seguinte versão alternativa de malloc:
void *mallocX (unsigned int nbytes) { void *ptr; ptr = malloc (nbytes); if (ptr == NULL) { printf ("Socorro! malloc devolveu NULL!\n"); exit (EXIT_FAILURE); } return ptr; }
A função mallocX não está em nenhuma biblioteca e é desconhecida fora dessas notas de aula. Ela é apenas uma abreviatura conveniente.
Eis como um vetor (= array) com n elementos inteiros pode ser alocado durante a execução de um programa (a propósito, veja observação sobre vetores e endereços em outra página):
int *v; int n, i; scanf ("%d", &n); v = mallocX (n * sizeof (int)); for (i = 0; i < n; i += 1) scanf ("%d", &v[i]); for (i = 0; i < n; i += 1) printf ("%d ", v[i]); free (v);
Do ponto de vista conceitual (mas apenas desse ponto de vista) o comando
v = mallocX (100 * sizeof (int));
tem o mesmo efeito que
int v[100];
A propósito, convém lembrar que o padrão ANSI não permite escrever "int v[n]", a menos que n seja uma constante, definida por um #define.
5 222 333 444 555 666
o seu programa deve imprimir
666 555 444 333 222
O seu programa não deve impor limitações sobre o valor de n.