Alocação de memória
Este artigo não cita fontes confiáveis. (Junho de 2013) |
Alocação de memória, em ciência da computação, consiste no processo de solicitar/utilizar memória durante o processo de execução de um programa de computador. A alocação de memória no computador pode ser dividida em dois grupos principais:
- Alocação Estática: os dados tem um tamanho fixo e estão organizados sequencialmente na memória do computador. Um exemplo típico de alocação estática são as variáveis globais e arrays. A alocação estática de memória tem como principal ponto positivo a simplicidade com que pode ser realizada pelos programadores, mantendo o algoritmo simples e de fácil organização das variáveis utilizadas. No entanto, como principal ponto negativo, a alocação estática ocupa uma porção fixa da memória, em casos em que essas variáveis não sejam utilizadas após um certo ponto, a alocação estática consome desnecessariamente esta porção reservada da memória, podendo levar o programa a fica muito pesado desnecessariamente. Apesar disso, é importante ressaltar, que na maioria das linguagens de programação, as variáveis criadas com alocação estática são liberadas automaticamente após o fim de uma determinada função.[1][2][3]
Em C, um exemplo de alocação estática é simplesmente a declaração de uma variável:
int variavel; //O tipo de dado pode ser qualquer um
- Alocação Dinâmica: os dados não precisam ter um tamanho fixo, pois é possível definir para cada dado quanto de memória que deseja-se usar. Sendo assim, aloca-se espaços de memória (blocos) que não precisam estar necessariamente organizados de maneira sequencial, podendo estar distribuídos de forma dispersa (não ordenada) na memória do computador. Na alocação dinâmica, é possível alocar/desalocar blocos de memória, de acordo com a necessidade, reservando ou liberando blocos de memória durante a execução de um programa. Para poder “achar” os blocos que estão dispersos ou espalhados na memória usa-se as variáveis do tipo
pointer
(indicadores de endereços de memória). É importante ressaltar que, na maioria das linguagens de programação que o gerenciamento de memória é manual, ou seja, feito pelo programador, as variáveis criadas com alocação dinâmica não são liberadas automaticamente após o fim de funções, sendo necessário liberá-las manualmente, e, por questões de segurança, é importante atribuir o "NULL" ao ponteiro criado.[1][2][3]
Em C, um exemplo de alocação dinâmica é o seguinte:
int *ponteiro;
ponteiro = (int *) malloc(sizeof(int));
//Nos padrões modernos da linguagem C, (int *) não é necessário.
Dessa forma, o ponteiro aponta para o endereço de memória contendo um espaço do tipo e tamanho da variável int
.[4]
Em C, um exemplo para limpar a memória alocada é o seguinte:
free(ponteiro);
ponteiro = NULL;
vale ressaltar que, para usar as funções malloc()
e free()
, é necessário incluir a biblioteca malloc.h
.[4]
A pilha e a heap são duas regiões da memória completamente distintas e com usos diferentes.
Pilha
editarA pilha é uma região da memória organizada de forma sequencial, ou seja, o primeiro valor a entrar na pilha, é o último a sair dela. A pilha é mais rápida e eficiente que a heap pela sua organização, mas seus valores não podem mudar de tamanho (algo de 8 bits não pode mudar para 16 bits, por exemplo).[1][2][3]
Na maioria das linguagens de programação modernas, a saída dos valores da pilha é automático e acontece quando o escopo acaba. Um exemplo em C seria:
//Não posso acessar as variáveis aqui, pois o escopo nem começou e as variáveis nem foram definidas
int main(void) {
int x = 1;
char y = 'A';
char *z = "Texto";
return 0;
}
//Também não posso acessá-las aqui, pois o escopo acabou, então elas não são mais acessíveis.
No exemplo acima, o escopo é a área delimitada pelas chaves. Cada uma dessas variáveis é uma variável na pilha, que não pode ser acessada fora do escopo em que foi definida, pois saem da pilha quando ele acaba.
Heap
editarA heap é outra região da memória organizada de forma não sequencial, portanto, ela não tem uma ordem exata. A vantagem da heap é: se uma variável precisar aumentar de capacidade, você pode alocar mais espaço na heap para armazenar um valor maior. Como desvantagem, ela é mais lenta de se acessar e interagir, pois não é sequencial. A alocação de memória na heap é a alocação dinâmica, explicada anteriormente.[1][2][3]
Nas linguagens com gerenciamento de memória manual, a alocação, realocação e desalocação são completamente manuais, por isso são considerados conceitos complexos, além de que podem causar vazamentos de memória.
#include <malloc.h>
int main() {
int *X = malloc(10 * sizeof(int));
if (!X) return 1;
X = realloc(X, 20 * sizeof(int));
if (!X) return 1;
free(X);
X = NULL;
return 0;
}
O exemplo acima mostra como alocar, realocar e liberar o espaço da memória. Pode parecer simples, mas a dificuldade é tanta que há uma linguagem de baixo nível que evita o gerenciamento de memória manual: Rust. Há várias regras sobre o uso da memória da heap, tornando-o complexo e um assunto difícil de possuir maestria completa.[4]
- ↑ a b c d «Difference between stack and heap»
- ↑ a b c d «Heap vs stack». Blog sobre Ciência da computação - Gustavo Pantuza. 18 de dezembro de 2016. Consultado em 15 de fevereiro de 2025
- ↑ a b c d «What is Ownership? - The Rust Programming Language». doc.rust-lang.org. Consultado em 15 de fevereiro de 2025
- ↑ a b c «Summary of Malloc (The GNU C Library)». www.gnu.org. Consultado em 15 de fevereiro de 2025