Os livros de linguagem de programação explicam que os tipos de valores são criados no etack, e os tipos de referência são criados no **heap***, sem explicar o que são estas duas coisas. Eu tenho'não li uma explicação clara sobre isso. Eu entendo o que uma pilha é. Mas..,
Pilha:
Sap:
delete
, delete[]
, ou free
.new
ou malloc
respectivamente.Exemplo:
int foo()
{
char *pBuffer; //<--nothing allocated yet (excluding the pointer itself, which is allocated here on the stack).
bool b = true; // Allocated on the stack.
if(b)
{
//Create 500 bytes on the stack
char buffer[500];
//Create 500 bytes on the heap
pBuffer = new char[500];
}//<-- buffer is deallocated here, pBuffer is not
}//<--- oops there's a memory leak, I should have called delete[] pBuffer;
**A Pilha*** Quando se chama uma função, os argumentos para essa função mais algumas outras despesas gerais são colocados na pilha. Algumas informações (tais como para onde ir no retorno) também são armazenadas lá. Quando você declara uma variável dentro da sua função, essa variável também é alocada na pilha.
Desalocar a pilha é muito simples porque você sempre desaloca na ordem inversa na qual você aloca. A pilha de coisas é adicionada à medida que você entra funções, os dados correspondentes são removidos à medida que você as sai. Isto significa que você tende a ficar dentro de uma pequena região da pilha, a menos que você chame muitas funções que chamam muitas outras funções (ou crie uma solução recursiva).
**O monte*** A pilha é um nome genérico para onde você coloca os dados que você cria na mosca. Se você não sabe quantas naves o seu programa vai criar, é provável que você use o novo (ou malloc ou equivalente) operador para criar cada nave espacial. Esta alocação vai ficar por aqui durante algum tempo, por isso é provável que libertemos as coisas numa ordem diferente da que criámos.
Assim, a pilha é muito mais complexa, porque acaba por haver regiões de memória que não são utilizadas entrelaçadas com pedaços que são - a memória fica fragmentada. Encontrar memória livre do tamanho que você precisa é um problema difícil. É por isso que a pilha deve ser evitada (embora ainda seja usada com frequência).
**Implantação*** A implementação tanto da pilha como da pilha é normalmente feita até o tempo de execução / SO. Muitas vezes jogos e outros aplicativos que são críticos para o desempenho criam suas próprias soluções de memória que pegam um grande pedaço de memória da pilha e depois a distribuem internamente para evitar depender do sistema operacional para a memória.
Isto só é prático se o seu uso de memória for bastante diferente da norma - ou seja, para jogos onde você carrega um nível em uma grande operação e pode jogar o lote inteiro fora em outra grande operação.
**Localização física na memória*** Isto é menos relevante do que você pensa por causa de uma tecnologia chamada Memória Virtual que faz seu programa pensar que você tem acesso a um determinado endereço onde os dados físicos estão em outro lugar (mesmo no disco rígido!). Os endereços que você obtém para a pilha estão em ordem crescente à medida que a sua árvore de chamadas se aprofunda. Os endereços para a pilha são imprevisíveis (ou seja, específicos da implantação) e, francamente, não são importantes.
A pilha é uma parte da memória que pode ser manipulada através de várias instruções de linguagem de montagem de teclas, tais como 'pop' (remover e retornar um valor da pilha) e 'push' (empurrar um valor para a pilha), mas também call (chamar uma sub-rotina - isto empurra o endereço para retornar à pilha) e return (retornar de uma sub-rotina - isto estala o endereço da pilha e salta para ela). É a região da memória abaixo do registro do ponteiro da pilha, que pode ser definida conforme necessário. A pilha também é usada para passar argumentos para as subrotinas, e também para preservar os valores nos registros antes de chamar as subrotinas.
A pilha é uma porção de memória que é dada a uma aplicação pelo sistema operacional, normalmente através de uma chamada de sistema como o malloc. Nos sistemas operacionais modernos esta memória é um conjunto de páginas que só o processo de chamada tem acesso.
O tamanho da pilha é determinado em tempo de execução, e geralmente não cresce após o lançamento do programa. Em um programa em C, a pilha precisa ser grande o suficiente para conter todas as variáveis declaradas dentro de cada função. A pilha crescerá dinamicamente conforme necessário, mas o sistema operacional está fazendo a chamada (muitas vezes a pilha crescerá mais do que o valor solicitado pelo malloc, de modo que pelo menos alguns mallocs futuros não precisarão voltar para o kernel para obter mais memória. Este comportamento é muitas vezes personalizável)
Como você alocou a pilha antes de lançar o programa, você nunca precisará distribuir a pilha antes de poder usar a pilha, então isso é uma pequena vantagem. Na prática, é muito difícil prever o que será rápido e o que será lento nos sistemas operacionais modernos que possuem subsistemas de memória virtual, pois como as páginas são implementadas e onde elas são armazenadas é um detalhe de implementação.