Você está na página 1de 15

24/10/22, 22:27 Aula 3 - Alocação Dinâmica de Memória - Prof.

Fernando De Siqueira - Estrutura de Dados

Aula 3 - Alocação Dinâmica de Memória


Alocação Estática e Alocação Dinâmica de
Memória

A alocação estática ocorre em tempo de compilação,


ou seja, no momento em que se define uma variável
ou estrutura é necessário que se definam seu tipo e
tamanho. Nesse tipo de alocação, ao se colocar o
programa em execução, a memória necessária para
utilizar as variáveis e estruturas estáticas precisa
ser reservada e deve ficar disponível até o término do
programa (rotina ou função).

A alocação dinâmica ocorre em tempo de execução,


ou seja, as variáveis e estruturas são declaradas sem
a necessidade de se definir seu tamanho, pois
nenhuma memória será reservada ao colocar o
programa em execução. Durante a execução do
programa, no momento em que uma variável ou parte
de uma estrutura precise ser utilizada, sua memória
será reservada e, no momento em que não for mais
necessária, deve ser liberada. Isso é feito com o
auxílio de comandos ou funções que permitem, por
meio do programa, reservar e/ou liberar memória. 

Pode-se dizer que os vetores e matrizes são estruturas


estáticas e, por esse motivo, devemos definir seu
número de posições. Algumas linguagens
permitem criar vetores dinâmicos por meio do uso de
ponteiros e sua memória é reservada durante a
execução do programa.

Mesmo vetores dinâmicos devem ter o seu tamanho


conhecido no momento da alocação da memória, pois
um vetor deve ter toda sua memória alocada antes da
sua utilização. 

Estruturas encadeadas dinâmicas possuem


tamanho variável, pois diferentemente de
vetores dinâmicos, sua memória é reservada por
elemento e não para toda a estrutura.

Desta forma, podemos afirmar que a alocação estática


de memória não proporciona a flexibilidade necessária
para a solução de todos os tipos de problema.
Sobretudo aqueles problemas onde não está claro
quais e quantos recursos, variáveis de memória,
devem ser alocados pelo programa.

https://sites.google.com/site/proffdesiqueiraed/aulas/aula-2---alocacao-dinamica-de-memoria 1/15
24/10/22, 22:27 Aula 3 - Alocação Dinâmica de Memória - Prof. Fernando De Siqueira - Estrutura de Dados

Alocação Dinâmica de Memória

Na declaração de um vetor é preciso dimensioná-lo, o


que significa que devemos saber, de antemão, quanto
espaço seria necessário, isto é, tínhamos de prover o
número máximo de elementos no vetor durante a
codificação. 

Esse pré-dimensionamento é um fator que limita em


muito a programação. Por exemplo,
se desenvolvermos um programa para calcular a
média e a variância das notas de uma prova, teremos
de prever o número máximo de alunos. Uma solução é
dimensionar o vetor com um número absurdamente
alto, para não termos limitações no momento
da utilização do programa. No entanto, isso levaria a
um desperdício de memória, o que é inaceitável em
diversas aplicações. Se, por outro lado, formos
modestos no pré-dimensionamento do vetor, o uso do
programa fica muito limitado, pois não conseguiríamos
tratar turmas com um número de alunos maior que o
previsto.

Felizmente, a linguagem C oferece meios de requisitar


espaços de memória em tempo de execução que é
usando alocação dinâmica de memória. 

Dizemos que podemos alocar memória


dinamicamente. Com esse recurso, nosso programa
para o cálculo da média e variância discutido antes
pode, em tempo de execução, consultar o número de
alunos da turma e então fazer a alocação do
vetor dinamicamente, sem desperdício de memória. 

O Uso da memória

Informalmente, podemos dizer que existem três


maneiras de reservar espaço de memória para o
armazenamento de informações:

A primeira é usar variáveis globais (e estáticas).


O espaço reservado para uma variável global
existe quanto o programa estiver sendo
executado.

A segunda maneira é usar variáveis locais. Nesse


caso, o espaço existe apenas enquanto a função
que declarou a variável está sendo executada,
sendo liberado para outros usos quando a
https://sites.google.com/site/proffdesiqueiraed/aulas/aula-2---alocacao-dinamica-de-memoria 2/15
24/10/22, 22:27 Aula 3 - Alocação Dinâmica de Memória - Prof. Fernando De Siqueira - Estrutura de Dados

execução da função termina. Por esse motivo, a


função que chama não pode fazer referência ao
espaço local da função chamada. As variáveis
globais ou locais podem ser simples ou vetores.
Para os vetores, precisamos informar o número
máximo de elementos; caso contrário, o
compilador não saberia o tamanho do espaço a
ser reservado.

A terceira maneira de reservar memória é


requisitar ao sistema, em tempo de
execução, um espaço de um terminado tamanho.
Esta é a alocação dinâmica de memória. Esse
espaço alocado dinamicamente
permanece reservado até que seja explicitamente
liberado pelo programa. Por isso, podemos
alocar dinamicamente um espaço de memória em
uma função e acessá-lo em outra. 

A partir do momento em que liberarmos o espaço, ele


estará disponibilizado para ser usado por outros
programas e não podemos mais acessá-lo. 

Se o programa não liberar um espaço alocado, ele


será automaticamente liberado quando a execução do
programa terminar portanto você não precisa ficar se
preocupando em ter que liberar a memória alocada
dinamicamente, porém esta é uma boa prática que
deve ser seguida pois o recurso da memória é
compartilhado por outros programas e pelo sistema
operacional.

Na figura abaixo, apresentamos um esquema didático


que ilustra de maneira fictícia a distribuição do uso da
memória pelo sistema operacional. Observe que o
sistema operacional reserva áreas diferentes na
memória para o programa, para as variáveis globais e
estáticas e para as variáveis alocadas dinamicamente.

Quando requisitamos ao  sistema operacional para


executar um determinado programa, o código em
linguagem de máquina do programa deve ser
carregado na memória. Todo programa para ser
executado precisa estar na memória do computador. 

O sistema operacional reserva também os espaços


necessários para armazenar as variáveis globais (e
estáticas) que foram declaradas no programa. 

https://sites.google.com/site/proffdesiqueiraed/aulas/aula-2---alocacao-dinamica-de-memoria 3/15
24/10/22, 22:27 Aula 3 - Alocação Dinâmica de Memória - Prof. Fernando De Siqueira - Estrutura de Dados

O restante da memória livre é utilizado pelas variáveis


locais e pelas variáveis alocadas dinamicamente. Cada
vez que uma determinada função é chamada, o
sistema reserva o espaço necessário para as variáveis
locais da função. Esse  espaço chama-se contexto de
execução e pertence  à pilha de execução e, quando a
função termina, é desempilhado. A parte da memória
não ocupada pela pilha de execução, isto é a memória
livre, pode ser requisitada dinamicamente. 

Se a pilha tentar crescer além do espaço disponível


existente, dizemos que ela “estourou”, e o programa é
abortado com erro. Da mesma forma, se o espaço
de memória livre for menor do que o espaço
requisitado dinamicamente, a alocação não é feita, e o
programa pode prever um tratamento de erro
adequado (por exemplo, podemos imprimir a
mensagem “Memória Insuficiente” e interromper a
execução do programa).

Funções para alocação dinâmica de memória

Na linguagem C, a alocação dinâmica de memória


pode ser realizada com apenas quatro chamadas a
funções:

void * malloc(int qty_bytes_alloc);


void * calloc(int qty, int size);
void * realloc(void * pointer, int new_size);
free( void * pointer);
https://sites.google.com/site/proffdesiqueiraed/aulas/aula-2---alocacao-dinamica-de-memoria 4/15
24/10/22, 22:27 Aula 3 - Alocação Dinâmica de Memória - Prof. Fernando De Siqueira - Estrutura de Dados

A função malloc permite que seja feita a alocação de


uma nova área de memória para uma estrutura. 

A função calloc tem a mesma funcionalidade


de malloc, exceto que devem ser fornecidos o
tamanho da área e a quantidade de elementos. 

A função realloc permite que uma área previamente


alocada seja aumentada ou diminuída e a função free
libera uma área alocada previamente com a função
malloc, calloc ou realloc.

Função malloc

É a função malloc que realiza a alocação de memória.


Deve-se informar para a função a quantidade de bytes
para alocação. A função irá retornar, se existir
memória suficiente, um endereço que deve ser
colocado em uma variável do tipo ponteiro.

Como a função retorna um ponteiro para o tipo void,


deve-se utilizar o operador de molde, transformando
este endereço para o tipo de ponteiro desejado.

Função calloc

Em vez de se alocar uma quantidade de bytes através


da função malloc, pode-se usar a função calloc e
especificar a quantidade de bloco de um determinado
tamanho. Funcionalmente a alocação irá ocorrer de
maneira idêntica. A única diferença entre o malloc e o
calloc é que a última função, além de alocar o espaço,
também inicializa o mesmo com zeros.

Função realloc

Às vezes é necessário redimensionar uma área


alocada. Para isto deve-se usar a função realloc.
Deve-se passar para ela o ponteiro retornado pelo
malloc e a indicação do novo tamanho. A realocação
de memória pode resultar na troca de blocos na
memória.

Função free

Quando não se deseja mais uma área alocada, deve-


se liberá-la através da função free. Deve ser passado
para a função o endereço, que se deseja liberar, que
foi devolvido quando a alocação da memória ocorreu.

https://sites.google.com/site/proffdesiqueiraed/aulas/aula-2---alocacao-dinamica-de-memoria 5/15
24/10/22, 22:27 Aula 3 - Alocação Dinâmica de Memória - Prof. Fernando De Siqueira - Estrutura de Dados

Usando as funções da biblioteca padrão para


Alocação Dinâmica de Memória

Um vetor nada mais é do que um ponteiro com


alocação estática de memória. 

A declaração int aVetor[10]; 

é equivalente a:

int *aVetor;
aVetor = (int *) malloc(10 * sizeof(int *));

Existem funções que estão presentes na biblioteca


padrão stdlib e que permitem alocar e liberar memória
dinamicamente. A função básica para alocar memória
é malloc. Ela recebe como parâmetro o número de
bytes que se deseja alocar e retorna o endereço de
memória inicial da área da memória alocada. 

Perceba que a função malloc retorna um endereço e


portanto esta informação deve ser armazenada em
um ponteiro. 

Para exemplificar, vamos considerar a alocação


dinâmica de um vetor de inteiros com 10 elementos.
Como a função malloc tem como valor de retorno o
endereço da área alocada e, nesse exemplo,
desejamos armazenar valores inteiros nessa área,
devemos declarar um ponteiro de inteiro para receber
o endereço inicial do espaço alocado. 

O trecho de código então seria:

int *v;
v = malloc(10*4);

Após esse comando, se a alocação for bem sucedida,


o ponteiro v armazenará o endereço inicial de uma
área contínua de memória suficiente para armazenar
10 valores inteiros. Podemos, então, tratar v como
tratamos um vetor declarado estaticamente, pois, se v
aponta para o início da área alocada, sabemos que
v[0] acessa o espaço o primeiro elemento a
ser armazenado, v[1] acessa o segundo, e assim por
diante (até v[9]). 

A forma como trabalhamos com variáveis declaradas


dinamicamente, sejam variáveis simples ou vetores, é
a mesma. Podemos atribuir valores, ler dados do
teclado, imprimir o conteúdo destas variáveis, etc.
Devemos contudo sempre lembrar que estas variáveis
são ponteiros e devem portanto ser tratadas como tal.
https://sites.google.com/site/proffdesiqueiraed/aulas/aula-2---alocacao-dinamica-de-memoria 6/15
24/10/22, 22:27 Aula 3 - Alocação Dinâmica de Memória - Prof. Fernando De Siqueira - Estrutura de Dados

O Operador sizeof()

No exemplo mostrado, consideremos que um inteiro


ocupa 4 bytes. Para ficarmos independentes de
compiladores e máquinas, usamos o operador sizeof().
O operador sizeof() retorna o tamanho necessário na
memória para um determinado tipo de dado. Ele deve
ser usado sempre em conjunto com a função malloc
para que o nosso código fique independente de
máquina e compilador. Isso porque dependendo da
máquina ou da versão do compilador o tamanho
necessário na memória para um determinado tipo de
dado pode variar de um compilador ou máquina para
outro. O tamanho para um tipo de dado sempre é
retornado em bytes.

v = malloc(10*sizeof(int));

O Operador de Molde de Tipo

Além disso, devemos salientar que a função malloc é


usada para alocar espaço para armazenar valores de
qualquer tipo. Por esse motivo, malloc retorna um
ponteiro genérico, para um tipo qualquer,
representado por void*, que deve ser
convertido automaticamente pela linguagem para o
tipo apropriado na atribuição. No entanto, é comum
fazer a conversão utilizando o operador de molde de
tipo (cast). O comando para a alocação do vetor de
inteiros fica então:

v = (int*) malloc (10*sizeof(int));

Assim, o ponteiro v aponta para o endereço inicial de


uma área contínua de memória para 10 inteiros. O
operador sizeof() obtém o tamanho em bytes do tipo
int e o operador de cast (int*), converte o ponteiro
genérico retornado por malloc para um ponteiro
do tipo int*.

A Figura abaixo, ilustra de maneira esquemática o que


ocorre na memória.

https://sites.google.com/site/proffdesiqueiraed/aulas/aula-2---alocacao-dinamica-de-memoria 7/15
24/10/22, 22:27 Aula 3 - Alocação Dinâmica de Memória - Prof. Fernando De Siqueira - Estrutura de Dados

Se, porventura, não houver espaço livre suficiente


para realizar a alocação, a função retorna um
endereço nulo (representado pelo símbolo NULL,
definido em stdlib.h).

É importante fazer o tratamento de erro adequado


quando for retornado o valor nulo. Por exemplo, se o
processamento adiante no programa depender da
alocação dinâmica de memória bem sucedida então
devemos alertar o usuário com uma mensagem e
finalizar a execução do programa com a função exit()
retornando um código de erro diferente de zero para
sinalizar a execução com erro do programa.

Podemos cercar o erro na alocação da memória


verificando o valor de retorno da função malloc. Por
exemplo, podemos imprimir uma mensagem e abortar
o programa com a função exit, também definida na
stdlib.

...
v = (int*) malloc (10*sizeof(int));
if (v == NULL)
{
printf(“Memoria insuficiente.\n”);
exit(1);
}
...

Liberando a Memória alocada Dinamicamente

Para liberar um espaço de memória alocado


dinamicamente, usamos a função free. Essa função
recebe como parâmetro o ponteiro da memória a ser
liberada. Assim, para liberar o vetor v, fazemos:

https://sites.google.com/site/proffdesiqueiraed/aulas/aula-2---alocacao-dinamica-de-memoria 8/15
24/10/22, 22:27 Aula 3 - Alocação Dinâmica de Memória - Prof. Fernando De Siqueira - Estrutura de Dados

free (v);

Só podemos passar para a função free um endereço


de memória que tenha sido alocado dinamicamente ou
seja ele precisa ter sido inicializado com o retorno da
função malloc anteriormente. 

Devemos lembrar ainda que não podemos acessar o


espaço da memória depois de liberado.

Para exemplificar o uso da alocação dinâmica, o


programa a seguir realiza o cálculo da média e da
variância. O programa lê o número de valores
fornecidos, aloca um vetor dinamicamente, captura os
valores e faz os cálculos.

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

/* Função para cálculo da média */


/* Objetivo: Calcula a média aritmética para um
conjunto de notas */
/* Parametros: int n - Tamanho do vetor e float *v -
Endereco do primeiro elemento do vetor de notas */
/* Valor de Retorno: float - Retorna a média
aritmética calculada */

float media(int n, float *v) {


    int i;
    float s = 0.0f;
    for(i=0; i<n; i++)
        s += v[i];
    return s/n;
}

/* função para cálculo da variância */


/* Objetivo: Calcula da Variancia para um conjunto de
notas */
/* Parametros: int n - Tamanho do vetor e float *v -
Endereco do primeiro elemento do vetor de notas */
/* Valor de Retorno: float - Retorna a variancia
calculada */

float variancia(int n, float *v, float m) {


    int i;
    float s = 0.0f;
    for(i=0; i<n; i++)
        s += (v[i] - m) * (v[i] - m);
    return s/n;
}

main() {

https://sites.google.com/site/proffdesiqueiraed/aulas/aula-2---alocacao-dinamica-de-memoria 9/15
24/10/22, 22:27 Aula 3 - Alocação Dinâmica de Memória - Prof. Fernando De Siqueira - Estrutura de Dados

    int i, n;
    float *v;
    float med, var;
    
    printf("Quantas notas serão lidas?: ");
    scanf("%i",&n);

    /*alocação dinâmica*/
    v = (float*) malloc (n*sizeof(float));

    /* tratamento de erro para alocação dinamica de


memoria mal sucedida */
    if(v == NULL) {
        printf("Memória Insuficiente");
        return 1;
    }

    /*leitura dos valores*/


    for(i=0; i<n; i++) {
        printf("Entre com a nota %i: ",i);
        scanf("%f", &v[i]);
    }

   /* Calculo da media e da variancia */


    med = media(n,v);
    var = variancia(n,v,med);

    /* Impressao do resultado */
    printf("Media: %.2f Variancia: %.2f \n", med, var);
    getche();

    /*libera memória*/
    free(v);
    return 0;
}

Exemplo de programa comentado com o uso de


ponteiro e da função malloc:

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

main() {
1    int *p, *q;
2    int x; 
3    p = (int*) malloc(sizeof(int));  // aloca
dinamicamente uma variavel do tipo  inteiro ( a
variavel é um ponteiro )
4    *p = 3;                                   // armazena 3 na
variavel p do tipo inteiro
5    q = p;                                    // faz o ponteiro q
receber o ponteiro p alocado

https://sites.google.com/site/proffdesiqueiraed/aulas/aula-2---alocacao-dinamica-de-memoria 10/15
24/10/22, 22:27 Aula 3 - Alocação Dinâmica de Memória - Prof. Fernando De Siqueira - Estrutura de Dados

6    printf("%d %d\n", *p, *q);     // imprime o


conteudo dos endereços apontados pelos ponteiros p e
q
7    x = 7;                                   // atribui o valor 7
a variavel x do tipo inteiro  
8    *q = x;                                 // atribui o valor da
variavel x ao conteudo do endereço apontado pelo
ponteiro q
9    printf("%d %d\n", *p, *q);   // imprime o
conteudo dos endereços apontados pelos ponteiros p e
q
10  p = (int*) malloc(sizeof(int)); // aloca
dinamicamente uma variavel do tipo inteiro 
11  *p = 5;                                  // armazena 5 na
variavel do tipo ponteiro
12  printf("%d %d\n", *p, *q);     //  imprime o
conteudo dos endereços apontados pelos ponteiros p e
q
13  getche();                             // aguarda o usuario
pressionar uma tecla qualquer para finalizar o
programa
}

No programa acima uma variável inteira é criada e seu


endereço é colocado em p. Em seguida, o
programa define o valor dessa variável como 3.
Depois o programa define q com o valor dessa
variável. O comando de atribuição é perfeitamente
válido porque uma variável ponteiro (q) está
recebendo a atribuição do valor de outro ponteiro
(p). Observe que, nesse ponto, *p e *q referem-se a
mesma variável. Posteriormente o programa,
portanto, imprime o conteúdo dessa variável (que é 3)
duas vezes.

A linha 7 define o valor de uma variável de inteiro, x,


com 7. A linha 8 muda o valor de *q para o valor de x.
Entretanto, como p e q apontam ambos para a mesma
variável, *p e *q têm o valor 7. Isso é ilustrado na
Figura 2 b). A linha 9, portanto, imprime o número 7
duas vezes.

A linha 10 cria uma nova variável inteira e coloca seu


endereço em p. Os resultados aparecem ilustrados na
Figura 2 c). Agora *p refere-se à variável inteira
recém-criada que ainda não recebeu um valor. q não
foi alterado; portanto, o valor de *q continua 7.

Observe que *p não se refere a uma única variável


específica. Seu valor muda em função do valor de p. A
linha 11 define o valor dessa variável recém-criada

https://sites.google.com/site/proffdesiqueiraed/aulas/aula-2---alocacao-dinamica-de-memoria 11/15
24/10/22, 22:27 Aula 3 - Alocação Dinâmica de Memória - Prof. Fernando De Siqueira - Estrutura de Dados

com 5, conforme ilustrado abaixo e a linha 12 imprime


os valores 5 e 7.

Exemplos de Alocação Dinâmica 

O programa abaixo. utiliza as funções malloc e realloc


para criar e aumentar o tamanho de um vetor
dinamicamente (em tempo de execução). No caso
de algum erro, as funções retornam um ponteiro nulo
(NULL) para indicar erro de alocação de memória.

/* programa_memoria_01.c */
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int *p;
    int i,k, n;
    
    printf("\nDigite a quantidade de numeros que serao
digitados ->");.
    scanf("%d", &i);

    /* 
    A função malloc reserva espaço suiciente para um
vetor de inteiros.
    Caso sejam digitados 5 elementos, serão
reservados 20 bytes, pois cada
    inteiro ocupa 4 bytes na memória 
https://sites.google.com/site/proffdesiqueiraed/aulas/aula-2---alocacao-dinamica-de-memoria 12/15
24/10/22, 22:27 Aula 3 - Alocação Dinâmica de Memória - Prof. Fernando De Siqueira - Estrutura de Dados

    */
    
    p = (int *)(malloc(i*sizeof(int)));
    if( p == NULL ) {
        printf("\nErro de alocacao de memoria");
        exit(1);
    }
    
    for( k=0;k<i;k++) {
        printf("Digite o numero para o indice %d ->",
k);
        scanf("%d", &p[k]);
    }
    
    for( k=0;k<i;k++) {
        printf("O numero do indice %d eh %d\n", k,
p[k]);
    }
    printf("\nDigite quantos elementos quer adicionar
ao vetor ->");
    scanf("%d", &n);
    
    /* A função realloc aumenta ou diminui o tamanho
do vetor dinamicamente. Ela recebe o ponteiro para o
vetor anterior e retorna o novo espaço alocado. */
    p = (int *)(realloc(p,(i+n)*sizeof(int)));
    if( p == NULL ) {
        printf("\nErro de re-alocacao de memoria");
        exit(1);
    }
    
    for(k=0;k<(n+i);k++) {
        printf("Digite o numero para o indice %d ->",
k);
        scanf("%d", &p[k]);
    }

    for( k=0;k<(i+n);k++) {
        printf("O numero do indice %d eh %d\n", k,
p[k]);
    }

    free(p);
    return 0;
}

Um outro exemplo com o uso da estrutura de dados


struct que também pode ser alocada dinamicamente
com as funções malloc ou calloc. 

O programa .abaixo trabalha com uma estrutura de


dados struct alocada dinamicamente. A estrutura
https://sites.google.com/site/proffdesiqueiraed/aulas/aula-2---alocacao-dinamica-de-memoria 13/15
24/10/22, 22:27 Aula 3 - Alocação Dinâmica de Memória - Prof. Fernando De Siqueira - Estrutura de Dados

possui nome e salario de um funcionário.

/* programa_memoria_03.c */
#include <stdio.h>
. #include <stdlib.h>

struct ST_DADOS {
    char nome[40];
    float salario;

    /* estrutura dentro de uma estrutura */


    struct nascimento {
        int ano;
        int mes;
        int dia;
    } dt_nascimento;
.
};

int main(void) {
    /* ponteiro para a estrutura */
    struct ST_DADOS * p;
..
    /* alocação de memória para o ponteiro da
estrutura */
    p = (struct ST_DADOS *) malloc(sizeof(struct
ST_DADOS));

    /* Um string (vetor de caracteres) é um ponteiro,


por isto a ausência do & no uso da função scanf */
    printf("\nEntre com o nome ->");
    scanf("%s", p->nome);
.
    printf("Entre com o salario ->");
    scanf("%f", &p->salario);
..
    /* O -> é chamado de pointer member (apontador
de membro). Ele é usado para referenciar um campo
da estrutura no lugar do ponto (.) */
    printf("Entre com o nascimento ->");
    scanf("%d%d%d", &p->dt_nascimento.dia, &p-
>dt_nascimento.mes, &p->dt_nascimento.ano);
.
    printf("\n===== Dados digitados ====");
    printf("\nNome = %s", p->nome);
    printf("\nSalario = %f", p->salario);
    printf("\nNascimento = %d/%d/%d\n", p-
>dt_nascimento.dia, p->dt_nascimento.mes, p-
>dt_nascimento.ano);

    /* Libera memoria alocada para o ponteiro de


estrutura */
https://sites.google.com/site/proffdesiqueiraed/aulas/aula-2---alocacao-dinamica-de-memoria 14/15
24/10/22, 22:27 Aula 3 - Alocação Dinâmica de Memória - Prof. Fernando De Siqueira - Estrutura de Dados

    free(p);

    getche();
    return 0;
}

https://sites.google.com/site/proffdesiqueiraed/aulas/aula-2---alocacao-dinamica-de-memoria 15/15

Você também pode gostar