Como a pilha funciona em c ++

o montão

é um bloco amorfo de memória que seu programa C ++ pode acessar, se necessário. Saiba mais sobre por que ela existe e como usá-lo.

Assim como é possível passar um ponteiro para uma função, é possível para uma função para retornar um ponteiro. Uma função que retorna o endereço de uma Duplo é declarada como segue:

double * fn (void) -

No entanto, você deve ter muito cuidado ao retornar um ponteiro. Para entender os perigos, você deve saber algo sobre o escopo de variáveis.

âmbito limitado em C ++

Slidar é o intervalo durante o qual uma variável é definida. Considere o seguinte trecho de código:

// a seguinte variável é acessível para // todas as funções e definidos, desde que o programa // está em execução (escopo global) int intGlobal - // o seguinte intChild variável é acessível // apenas para a função e só é definido // contanto como C ++ é criança execução () ou uma função // qual criança () chama (escopo função) criança (void) {int intChild - //} a seguinte intParent variável tem função // pai scopevoid (void) {int intParent = 0-criança () - int = 0 intLater-intParent = intLater-} int principal (int nargs, char * pArgs []) {progenitor () -}

Este fragmento programa começa com a declaração de uma variável intGlobal. Esta variável existe a partir do momento o programa começa a executar até que ele termina. Você diz que intGlobal “Tem escopo do programa.” Você também dizer que a variável “entra em escopo” antes mesmo da função a Principal() é chamado.

Video: C++ - Aula 28 - Pilha / Stack - Parte 1

A função a Principal() invoca imediatamente pai (). A primeira coisa que o processador vê em pai () é a declaração de intParent. Nesse ponto, intParent entra no âmbito de aplicação - isto é, intParent é definido e disponível para o restante da função pai ().

A segunda declaração em pai () é a chamada para criança(). Mais uma vez, a função criança() declara uma variável local, desta vez intChild. O âmbito da variável intChild está limitado à função criança(). tecnicamente, intParent não é definido no âmbito da criança() Porque criança() não têm acesso a intParent- no entanto, a variável intParent continua a existir enquanto criança() é execução.

Quando criança() saídas, a variável intChild sai do escopo. Não só é intChild não acessível, não existe mais. (A memória ocupada por intChild é devolvido ao conjunto geral a ser usado para outras coisas.)

Como pai () continua a execução, a variável intLater entra no âmbito da declaração. No ponto em que pai () volta para a Principal(), ambos intParent e intLater ir fora do escopo.

Video: Programação em C/C++ - Aula 34 - Pilha dinâmica

Porque intGlobal é declarado globalmente neste exemplo, ele está disponível para todas as três funções e permanece disponível para a vida do programa.

Examinando o problema âmbito em C ++

O segmento de código a seguir compila sem erro, mas não funciona (não é apenas odeio isso?):

Video: Pilha que funciona com água - Será Que Isso Funciona?



double * criança (void) {dLocalVariable-retorno dupla &dLocalVariable-} pai void (void) {double * pdLocal-pdLocal = child () - * pdLocal = 1.0-}

O problema com esta função é que dLocalVariable é definido apenas no âmbito da função criança(). Assim, no momento em que o endereço de memória dLocalVariable é retornado de criança(), refere-se a uma variável que não existe mais. A memória que dLocalVariable anteriormente ocupado provavelmente está sendo usado para outra coisa.

Esse erro é muito comum, porque ele pode rastejar acima em um número de maneiras. Infelizmente, esse erro não causar o programa para parar instantaneamente. Na verdade, o programa pode funcionar bem na maioria das vezes - ou seja, o programa continua a funcionar enquanto a memória anteriormente ocupado pelo dLocalVariable não é reutilizado imediatamente. Tais problemas intermitentes são os mais difíceis de resolver.

Proporcionando uma solução utilizando a pilha em C ++

O problema âmbito originou porque C ++ levou de volta a memória definido localmente antes de o programador estava pronto. O que é necessário é um bloco de memória controlado pelo programador. Ela pode alocar a memória e colocá-lo de volta quando ela quer - não porque C ++ acha que é uma boa idéia. Tal bloco de memória é chamado de heap.

memória heap é alocado usando o Novo palavra-chave, seguido pelo tipo de objecto a ser alocado. o Novo comando quebra um pedaço de memória fora do montão grande o suficiente para segurar o tipo especificado de objeto e retorna o seu endereço. Por exemplo, o seguinte aloca um Duplo variável fora da pilha:

double * criança (void) {double * pdLocalVariable = new double-retorno pdLocalVariable-}

Esta função agora funciona corretamente. Embora a variável pdLocalVariable sai do escopo quando a função criança() retornos, a memória para o qual pdLocalVariable refere-se não o faz. A posição de memória retornado por Novo não sai do escopo até que seja explicitamente voltou para a pilha usando a palavra-chave excluir, que é especificamente projetado para essa finalidade:

pai (void) {// child () retorna o endereço de um bloco de // da memorydouble pilha * pdMyDouble = child () - // armazenar um valor lá * pdMyDouble = 1,1 - // ... // agora devolver o memória para o heapdelete pdMyDouble-pdMyDouble = 0 - // ...}

Aqui, o ponteiro retornado por criança() é usado para armazenar um valor duplo. Depois que a função terminou com a localização de memória, ele é retornado para a pilha. A função pai () define o ponteiro para 0 depois da memória heap foi devolvido - este não é um requisito, mas é uma idéia muito boa.

Se o programador erroneamente tenta armazenar algo em * pdMyDouble depois de excluir, o programa irá falhar imediatamente com uma mensagem de erro significativa.

Você pode usar Novo para alocar matrizes da pilha, bem como, mas você deve retornar um array usando o excluir[] palavra-chave:

Video: Como Funciona? - Pilha

int * nArray = new int [10] -nArray [0] = 0-delete [] nArray-

tecnicamente new int [10] invoca a Novo[] operador mas funciona da mesma forma Novo.


Publicações relacionadas