Buscar

Tipos de Alocação de Memória

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 15 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 15 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 15 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

1
Tipos de Alocação de Memória
Tecnologia(s) C
Complexidade Média
Fonte Faculdade , ChatGPT
Status Completo
 C
int numeroInteiro; // O compilador reserva 4 bytes para um inteiro 
padrão de 32 bits.
char caractere; // O compilador reserva 1 byte para um 
caractere.
float numeroReal; // O compilador reserva 4 bytes para um número 
de ponto flutuante.
Alocação Estática
Refere-se à reserva de espaço de memória durante a compilação do programa.•
O tamanho da memória alocada permanece constante durante toda a execução do 
programa
Critério utilizado para determinar quanto espaço na memória é necessário para 
armazenar uma variável:
Depende do tipo de dado da variável. Cada tipo de dado em uma linguagem de 
programação tem um tamanho associado, que é definido pelo compilador. 
•
Os tamanhos padrão dos tipos de dados podem variar entre diferentes linguagens 
de programação e compiladores, mas geralmente seguem um padrão comum.
•
Exemplos comuns de tamanhos de tipos de dados em C�•
int� Geralmente, 4 bytes em sistemas de 32 bits e 8 bytes em sistemas de 64 
bits.
•
char� Normalmente, 1 byte.•
float� Geralmente, 4 bytes.•
double� Geralmente, 8 bytes.•
Exemplos
2
 C
// A função sizeof() retorna o número de bytes necessários para 
armazenar o tipo de dado ou a variável especificada:
#include <stdio.h>
int main() {
 printf("Tamanho de int: %zu bytes\n", sizeof(int));
 printf("Tamanho de char: %zu byte\n", sizeof(char));
 printf("Tamanho de float: %zu bytes\n", sizeof(float));
 return 0;
}
 C
#include <stdlib.h>
int main() {
 int *ponteiroInteiro = (int *)malloc(sizeof(int));
 // Alocou memória, mas não liberou
 // Se essa linha for removida, haverá um vazamento de memória
 return 0;
}
Variáveis alocadas estaticamente existem desde o início até o término da execução do 
programa (tempo de vida da variável = tempo de execução do programa).
•
O espaço de memória é liberado automaticamente no encerramento do programa.•
Essas variáveis são armazenadas no segmento de dados.•
Vantagens
Acesso rápido, já que a localização na memória é conhecida antecipadamente.•
Não há risco de vazamento de memória.
Memory Leak
Ocorre quando um programa aloca dinamicamente memória durante sua 
execução, mas falha em liberar ou desalocar essa memória antes de encerrar.
•
Resulta em acúmulo progressivo de memória não utilizada ao longo do tempo 
(consumo excessivo de recursos → falhas no programa ou no sistema).
•
É responsabilidade do programador liberar a memória alocada dinamicamente:
O programa aloca dinamicamente um espaço de memória para armazenar um 
inteiro, mas não utiliza a função free para liberar essa memória antes de encerrar 
o programa. Isso resulta em um vazamento de memória, pois o espaço alocado 
não é recuperado, mesmo quando o programa não precisa mais dele.
3
Desvantagens
Limitações na flexibilidade, pois o tamanho precisa ser conhecido antecipadamente.•
Ineficiente para lidar com dados cujo tamanho não pode ser determinado até o tempo de 
execução.
Essa situação é comum quando lida-se com estruturas de dados dinâmicas, como 
listas encadeadas, árvores, ou arrays cujo tamanho precisa ser ajustado 
dinamicamente com base nos dados de entrada ou em condições durante a 
execução do programa.
Listas Encadeadas:1.
Suponha que você esteja construindo uma lista encadeada, e você não sabe 
quantos elementos ela terá até que os dados de entrada sejam processados 
durante a execução do programa. Nesse caso, você pode precisar alocar 
dinamicamente memória para cada novo nó na lista à medida que os dados 
são lidos.
•
Leitura de Dados Externos:2.
Se você estiver lendo dados de um arquivo ou de uma fonte externa e o 
número de elementos não é conhecido até a execução do programa, você 
pode precisar alocar memória dinamicamente para armazenar esses dados.
•
Redimensionamento Dinâmico de Arrays:3.
Suponha que você esteja construindo um array que precisa ser 
redimensionado conforme os dados são processados. Se o tamanho não 
puder ser determinado até o tempo de execução, a alocação dinâmica de 
memória pode ser mais adequada do que a alocação estática.
•
Em contraste, a alocação estática de memória, que ocorre em tempo de compilação, 
exige que o tamanho seja conhecido antecipadamente. Se você souber exatamente 
quantos elementos sua estrutura de dados terá e esse número for constante durante 
a execução do programa, a alocação estática pode ser mais eficiente e direta.
Em C, a alocação estática de variáveis acontece por padrão para variáveis globais. 
Para variáveis locais (dentro de funções), você precisa usar a palavra-chave static 
para indicar que deseja uma alocação estática. Aqui estão alguns exemplos para 
ilustrar isso:
Variáveis Globais
Exemplo
4
 C
#include <stdio.h>
int globalVariable = 10; // Alocada estaticamente
int main() {
 printf("Global Variable: %d\n", globalVariable);
 return 0;
}
 C
#include <stdio.h>
void exampleFunction() {
 static int staticVariable = 5; // Alocada estaticamente
 printf("Static Variable: %d\n", staticVariable);
 staticVariable++; // Mantém o valor entre chamadas da função
}
int main() {
 exampleFunction(); // Chama a função
 exampleFunction(); // Chama novamente
 return 0;
}
No exemplo acima, globalVariable é uma variável global e será alocada 
estaticamente. Isso significa que ela será inicializada uma vez, antes do início da 
execução do programa, e manterá seu valor ao longo do tempo de vida do 
programa.
Variáveis Locais Estáticas
Exemplo
Neste exemplo, staticVariable é uma variável local da função exampleFunction, mas 
a palavra-chave static é usada para indicar que ela deve ser alocada estaticamente. 
Isso significa que ela será inicializada uma vez, e seu valor será mantido entre 
chamadas sucessivas da função.
A função exampleFunction() é chamada duas vezes consecutivas, portanto, o valor 
da variável staticVariable será o seguinte:
Na primeira chamada:
A variável staticVariable é inicializada com o valor 5.•
O valor de staticVariable é impresso como 5.•
A variável staticVariable é incrementada para 6 na primeira chamada da 
função.
•
Na segunda chamada:
5
 C
#include <stdio.h>
static int a = 0; // variável global, alocação estática
void incrementa(void) {
 int b = 0; // variável local, alocação automática
 static int c = 0; // variável local, alocação estática
 printf("a: %d, b: %d, c: %d\n", a, b, c);
 a++;
 b++;
 c++;
}
int main(void) {
 int i;
 for (i = 0; i < 5; i++)
 incrementa();
 system("pause");
 return 0;
}
// Saída:
// a: 0, b: 0, c: 0
// a: 1, b: 0, c: 1
// a: 2, b: 0, c: 2
// a: 3, b: 0, c: 3
// a: 4, b: 0, c: 4
Como staticVariable é uma variável estática, seu valor não é reiniciado 
para 5.
•
Em vez disso, o valor de staticVariable mantém-se como 6, que foi o 
valor após a primeira chamada.
•
Portanto, o valor de staticVariable é impresso novamente como 6.•
Depois, staticVariable é incrementada novamente, tornando-se 7.•
Se a variável não fosse estática, o valor de staticVariable seria sempre reiniciado 
para 5 a cada chamada da função, resultando em uma saída de 6 em ambas as 
chamadas da função.
Exemplo
A cada chamada da função incrementa(), as variáveis a, b e c são impressas na 
tela e depois tem seu valor incrementado.
•
A variável global a é incrementada a cada chamada da função, então seu valor 
será de 0 a 4 após as cinco chamadas.
•
A variável local automática b é inicializada com 0 a cada chamada, então sempre 
será impressa como 0.
•
6
A variável local estática c é incrementada a cada chamada, mas seu valor é 
mantido entre chamadas, então será de 0 a 4 após as cinco chamadas.
•
Primeira chamada
Variáveis: a � 0, b � 0, c � 0•
Saída: a: 0, b: 0, c: 0•
Após incrementos: a � 1, b � 1, c � 1•
Segunda chamada
Variáveis: a � 1, b � 0, c � 1•
Saída: a: 1, b: 0, c: 1•
Após incrementos: a � 2, b � 1, c � 2•
Terceira chamada
Variáveis:a � 2, b � 0, c � 2•
Saída: a: 2, b: 0, c: 2•
Após incrementos: a � 3, b � 1, c � 3•
Quarta chamada
Variáveis: a � 3, b � 0, c � 3•
Saída: a � 3, b � 0, c � 3•
Após incrementos: a � 4, b � 1, c � 4•
Quinta chamada
Variáveis: a � 4, b � 0, c � 4•
Saída: a � 4, b � 0, c � 4•
Após incrementos: a � 5, b � 1, c � 5•
Então, para resumir:
Para variáveis globais, a alocação estática acontece automaticamente.•
Para variáveis locais, você precisa usar a palavra-chave static para indicar alocação 
estática.
•
Alocação Automática
Gerenciamento Automático de Memória� Nesse método de alocação, o sistema gerencia 
automaticamente a memória para as variáveis locais da função, reservando espaço quando 
a função é chamada e liberando-o quando a função é encerrada.
•
Alocação na Pilha de Execução: A memória para variáveis de alocação automática é 
tipicamente alocada na pilha de execução, uma área de memória gerenciada pelo sistema 
operacional.
•
7
 C
void *malloc (size_t size)
Tempo de Vida Atrelado à Função: O tempo de vida dessas variáveis está diretamente 
ligado à execução da função. Elas são automaticamente liberadas quando a função é 
concluída, garantindo que o espaço de memória que ocupam seja recuperado 
automaticamente.
•
Inicialização Opcional: Variáveis alocadas automaticamente não exigem inicialização 
explícita, embora seus valores iniciais possam ser imprevisíveis se não forem inicializados 
explicitamente pelo programador.
•
Eficiência para Dados Temporários: Esse método é eficiente para variáveis de curta 
duração, como aquelas usadas dentro do escopo de uma função. A alocação e desalocação 
de memória na pilha são operações rápidas, tornando-o adequado para dados temporários.
•
Alocação Dinâmica
Uma área da memória é requisitada explicitamente pelo programada durante sua execução.•
O controle das áreas alocadas dinamicamente pode ser manual ou semiautomático, 
portanto, o programa solicita e libera memória conforme necessário ou quando o programa 
encerrar.
•
A liberação das áreas alocadas é realizada pelo programador.•
Esses dados são armazenados no segmento Heap.•
É realizada principalmente por meio de funções como malloc(), calloc(), realloc() e free()•
Alocação Dinâmica Simples
Função malloc
É usada para alocar um bloco de memória (bytes) de tamanho específico durante a 
execução do programa. 
•
Retorna um Ponteiro para o primeiro byte alocado ou NULL se a alocação falhar.•
Exemplos
Exemplo 01
8
 C
#include <stdio.h>
#include <stdlib.h>
int main() {
 int *ptr; // Ponteiro para int (4 bytes)
 // Aloca espaço para um único inteiro (4 bytes)
 ptr = (int*)malloc(sizeof(int));
 if (ptr == NULL) {
 printf("Erro ao alocar memória!");
 return 1;
 }
 // Usa o espaço alocado
 *ptr = 42;
 // Libera o espaço alocado quando não for mais necessário
 free(ptr);
 return 0;
}
Exemplo 02
9
 C
#include <stdio.h>
#include <stdlib.h>
int main() {
 int *p;
 int n = 5; // quantidade de elementos alocados
 // A função malloc() aloca memória no heap para armazenar n 
inteiros.
 // sizeof(int) é usado para garantir que o espaço alocado seja 
suficiente para armazenar um inteiro.
 p = (int*)malloc(n * sizeof(int));
 if (p == NULL) {
 printf("Falha ao alocar memória\n");
 exit(1); // Sai do programa indicando erro
 }
 // Atribui valores aos elementos alocados
 // Neste caso, os elementos são preenchidos com números pares.
 for (int i = 0; i < n; i++) {
 p[i] = i * 2;
 }
 // Imprime os valores atribuídos
 for (int i = 0; i < n; i++) {
 printf("%d ", p[i]);
 }
 printf("\n");
 // Libera a memória alocada
 free(p);
 return 0;
}
 C
void *realloc(void *ptr, size_t newsize);
Função realloc
ptr: Ponteiro para o bloco de memória previamente alocado dinamicamente, a qual 
deseja-se realocar. 
•
Se ptr foi NULL , realloc() funcionará como malloc()•
É utilizada para redimensionar um bloco de memória que já havia sido alocado 
anteriormente.
•
10
 C
#include <stdio.h>
#include <stdlib.h>
int main() {
 int *ptr;
 int n = 5;
 // Alocando memória inicialmente
 ptr = (int *)malloc(n * sizeof(int));
 if (ptr == NULL) {
 printf("Erro ao alocar memória.\n");
 exit(1);
 }
 // Imprimindo os valores originais
 printf("Valores originais:\n");
 for (int i = 0; i < n; i++) {
 ptr[i] = i;
 printf("%d ", ptr[i]);
 }
 printf("\n");
 // Realocando memória para armazenar mais elementos
 n = 10;
 ptr = (int *)realloc(ptr, n * sizeof(int));
 if (ptr == NULL) {
 printf("Erro ao realocar memória.\n");
 exit(1);
 }
 // Imprimindo os valores atualizados
 printf("Valores atualizados:\n");
 for (int i = 0; i < n; i++) {
 printf("%d ", ptr[i]);
 }
 printf("\n");
 // Liberando a memória alocada
 free(ptr);
 return 0;
}
É recomendável atribuir o resultado de realloc() a um novo ponteiro, porque se a 
realocação falhar e realloc() retornar NULL , o acesso ao bloco de memória original 
não terá sido alterado.
•
Exemplo
Output
11
 C
void free(void *ptr)
Valores originais:
0 1 2 3 4
Valores atualizados:
0 1 2 3 4 0 0 0 0 0
Este código aloca inicialmente espaço para armazenar 5 inteiros. Depois, ele realoca 
espaço para armazenar 10 inteiros e imprime os valores atualizados. Por fim, libera a 
memória alocada antes de terminar.
Função free
ptr: É o o ponteiro para o bloco de memória previamente alocado que deseja-se liberar.
Ao chamar a função free(prt), o bloco de memória que havia sido alocado 
anteriormente pelo ponteiro ptr é marcado como livre e disponível para reutilização 
pelo sistema.
•
Entretando, o ponteiro ptr continua apontando para o endereço de memória 
liberadao e por isso é aconselhável mudar seu valor para NULL após a liberação.
•
Exemplo
12
 C
#include <stdio.h>
#include <stdlib.h>
int main() {
 // Aloca memória dinamicamente para armazenar um inteiro
 int *ptr = (int *)malloc(sizeof(int));
 
 if (ptr == NULL) {
 printf("Falha ao alocar memória\n");
 return 1; // Sai do programa indicando erro
 }
 *ptr = 10; // Atribui um valor ao inteiro alocado dinamicamente
 
 printf("Valor antes de liberar a memória: %d\n", *ptr);
 
 // Libera a memória alocada
 free(ptr);
 
 // Após liberar a memória, ptr ainda aponta para o endereço de 
memória liberado
 // É uma boa prática definir o ponteiro como NULL após liberar a 
memória
 ptr = NULL;
 // Tentativa de acesso ao conteúdo da memória liberada, o que pode 
causar comportamento indefinido
 printf("Valor após liberar a memória: %d\n", *ptr);
 return 0;
}
Em resumo:
Função Ação Sintaxe
malloc(
)
Aloca um determinado 
número de bytes na 
memória e retorna um 
ponteiro para o primeiro 
byte alocado. Se não for 
possível alocar, a 
função retorna NULL
#include <stdlib.h>
void *malloc(size_t 
size)
free() Libera o número de 
bytes alocados 
previamente na 
memória, apontados por 
ptr
#include <stdlib.h> 
void ree (void 
*ptr)
13
 C
void* calloc(size_t num_elements, size_t element_size);
realloc
()
Redimensiona a área 
previamente alocada, 
apontada por ptr , para 
o novo tamanho 
newsize .
#include <stdlib.h> 
void *realloc(void 
*ptr size_t 
newsize)
Alocação Dinâmica por Vetor
É usada para alocar memória para uma sequência de elementos de um determinado tipo 
de dados.
•
Em C, uma das maneiras de alocar memória para um vetor é usando a função calloc() .•
Função calloc
Parâmetros
num_elements � Número de elementos a serem alocados.•
element_size � Tamanho de cada elemento em bytes.•
Retorno
Retorna um ponteiro para a região da memória alocada, que pode ser convertida para 
o tipo de dado desejado.
Funcionamento
calloc() aloca espaço na memória para um vetor com num_elements , cada um 
tendo o tamanho especificado em element_size .
•
A função retorna umponteiro para a região de memória alocada.•
A memória alocada é inicializada com zeros.•
Se a alocação falhar, calloc() retorna NULL .•
Exemplo
14
 C
#include <stdio.h>
#include <stdlib.h>
int main() {
 int *vetor;
 int num_elementos = 5;
 // Aloca espaço para um vetor de 5 inteiros
 vetor = (int*)calloc(num_elementos, sizeof(int));
 // Verifica se a alocação foi bem-sucedida
 if (vetor == NULL) {
 printf("Erro: Não foi possível alocar memória.");
 return 1;
 }
 // Preenche o vetor com alguns valores
 for (int i = 0; i < num_elementos; i++) {
 vetor[i] = i * 10;
 }
 // Imprime os valores do vetor
 printf("Valores do vetor:\n");
 for (int i = 0; i < num_elementos; i++) {
 printf("%d ", vetor[i]);
 }
 // Libera a memória alocada
 free(vetor);
 return 0;
}
Diferença entre malloc() e calloc()
Característic
a
malloc() calloc()
Inicialização Não inicializa a 
memória alocada.
Inicializa toda a 
memória alocada com 
zeros.
Parâmetros Recebe apenas o 
tamanho em bytes do 
bloco.
Recebe o número de 
elementos e o 
tamanho de cada um.
Exemplo
15
 C
#include <stdio.h>
#include <stdlib.h>
int main() {
 int *ptr_malloc, *ptr_calloc;
 // Usando malloc para alocar espaço para um único inteiro
 ptr_malloc = (int*)malloc(sizeof(int));
 // Usando calloc para alocar espaço para um único inteiro
 ptr_calloc = (int*)calloc(1, sizeof(int));
 if (ptr_malloc == NULL || ptr_calloc == NULL) {
 printf("Erro: Não foi possível alocar memória.\n");
 return 1;
 }
 printf("Conteúdo de ptr_malloc: %d\n", *ptr_malloc); // Pode ser um 
valor aleatório
 printf("Conteúdo de ptr_calloc: %d\n", *ptr_calloc); // Deve ser 0
 // Liberando a memória alocada
 free(ptr_malloc);
 free(ptr_calloc);
 return 0;
}

Continue navegando