Logo Passei Direto
Buscar
Material
páginas com resultados encontrados.
páginas com resultados encontrados.
left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

Prévia do material em texto

Ponteiros e alocação dinâmica de 
memória
Apresentação
Na linguagem C++, ponteiros são recursos importantes que podem ser utilizados para desempenhar 
diversas atividades envolvendo o acesso direto à memória. Por meio de ponteiros, programadores 
podem escrever algoritmos dinâmicos e otimizados, que consomem menos recursos e executam 
suas rotinas e funções de modo mais rápido e eficiente.
Nesta Unidade de Aprendizagem, você vai estudar sobre ponteiros e alocação dinâmica de 
memória. Para isso, você deverá aprender a identificar um ponteiro, bem como verá o 
funcionamento da alocação dinâmica de memória e como é feita a implementação de um ponteiro.
Bons estudos.
Ao final desta Unidade de Aprendizagem, você deve apresentar os seguintes aprendizados:
Identificar um ponteiro.•
Reconhecer como funciona a alocação dinâmica de memória.•
Implementar um ponteiro.•
Desafio
A série Fibonacci é representada por: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, etc. Essa série 
começa com os elementos 0 e 1 e, na sequência, os elementos posteriores representam a soma dos 
dois elementos anteriores.
Essa série foi descoberta pelo matemático Leonardo Fibonacci, a partir da observação do 
crescimento populacional de coelhos, e é conhecida como um exemplo clássico no aprendizado de 
linguagens de programação.
Com base nisso, elabore um algoritmo em C++ que leia um número pelo teclado e apresente a 
sequência Fibonacci até o total de elementos desse número. Crie um vetor do tamanho do número 
lido e armazene a sequência nesse vetor. Por fim, imprima o conteúdo do vetor e a posição de 
memória de cada elemento, conforme o seguinte modelo:
Entre o MAX: 15 
0 0x2ca1a90 
1 0x2ca1a94 
1 0x2ca1a98 
2 0x2ca1a9c 
3 0x2ca1aa0 
5 0x2ca1aa4 
8 0x2ca1aa8 
13 0x2ca1aac 
21 0x2ca1ab0 
34 0x2ca1ab4 
55 0x2ca1ab8 
89 0x2ca1abc 
144 0x2ca1ac0 
233 0x2ca1ac4 
377 0x2ca1ac8
Declare o vetor que vai armazenar os elementos da série e a variável MAX por meio da alocação 
dinâmica de memória (new) e não se esqueça de liberar a memória no final da execução (delete).
Infográfico
A linguagem C++ possui a capacidade de acessar, diretamente, partes da memória para realizar 
diversas operações, como, por exemplo, declarar ponteiros para otimizar a execução de algoritmos.
Um ponteiro, por sua vez, é uma variável que armazena o endereço de memória de outra variável 
do mesmo tipo de dado. A declaração de um ponteiro é realizada pela indicação do caractere * e o 
endereço de uma variável é atribuído a um ponteiro pela indicação do caractere &.
Veja, no Infográfico a seguir, a declaração e a atribuição de variáveis e ponteiros, bem como a sua 
representação na memória.
Conteúdo do livro
Implementar sistemas pode se tornar uma atividade prazerosa quando o programador conhece e 
utiliza os melhores recursos fornecidos pela linguagem de programação utilizada. C++ é uma 
linguagem conhecida por disponibilizar diversos recursos que permitem escrever códigos enxutos, 
otimizados e de fácil entendimento. Entre esses recursos, destacam-se os ponteiros, que permitem 
acessar diretamente endereços de memória, bem como alocar memória de forma dinâmica, 
consumindo menos recursos para produzir programas com mais desempenho e eficiência.
Para saber mais, acompanhe a leitura do capítulo Ponteiros e alocação dinâmica de memória, da 
obra Linguagem de programação, que serve como base teórica para esta Unidade de Aprendizagem.
Boa leitura.
LINGUAGEM DE 
PROGRAMAÇÃO
Maurício de Oliveira Saraiva
Ponteiros e alocação 
dinâmica de memória
Objetivos de aprendizagem
Ao final deste texto, você deve apresentar os seguintes aprendizados:
 � Identificar um ponteiro.
 � Reconhecer como funciona a alocação dinâmica de memória.
 � Implementar um ponteiro.
Introdução
Implementar sistemas pode se tornar uma atividade prazerosa quando 
o programador utiliza os melhores recursos fornecidos pela linguagem 
de programação, como a C++, a qual é conhecida por disponibilizar 
diversos recursos que permitem escrever códigos enxutos, otimizados 
e de fácil entendimento. 
Neste capítulo, você conhecerá um pouco sobre esses recursos, como 
os ponteiros, com os quais se acessa diretamente endereços de memória, 
bem como se aloca de forma dinâmica, consumindo menos recursos para 
produzir programas com mais desempenho e eficiência.
Identificação de um ponteiro
Quando se declara uma variável, o programa reserva na memória um espaço 
para acomodar um valor que seja do tamanho do tipo de dados dessa variável. 
Por exemplo, a seguinte expressão, escrita na linguagem C++, declara uma 
variável do tipo int, que destina um espaço de quatro bytes para armazenar o 
valor 30 em determinado endereço na memória (VOTRE, 2016).
Sabendo que toda variável declarada está armazenada em algum local na 
memória, pode-se afirmar que ela também possui um endereço. Na linguagem 
C++, esse endereço é acessado pelo operador & (VOTRE, 2016).
Um ponteiro, por sua vez, é uma variável que armazena o endereço de 
memória de outra variável, o qual faz referência a um valor específico, em vez 
de guardar um valor. Assim, ele faz uma referência indireta a um valor; já um 
nome de variável se refere diretamente a um valor (DEITEL; DEITEL, 2011). 
A declaração de um ponteiro é realizada pela indicação de um tipo de dado 
seguida do operador * antes do nome da variável. Isso significa que ela será um 
ponteiro para uma variável do mesmo tipo de dado, por exemplo, um inteiro.
Um ponteiro sempre deve ser inicializado ao ser declarado. Nessa declaração, ele pode 
apontar para NULL, o que significa que não está se referindo a nenhuma variável ou 
diretamente ao seu endereço (DEITEL; DEITEL, 2011).
Na Figura 1, você pode ver a ilustração do acesso de um ponteiro em uma 
variável. Nela, identifica-se que uma variável é dividida em duas partes, en-
dereço e valor, que podem ser acessadas pelo ponteiro de forma independente 
— ele pode acessar tanto um como o outro.
Ponteiros e alocação dinâmica de memória2
Figura 1. Estrutura de uma variável.
ponteiro variável
pIdade
*pIdade
0x70fe34
30
endereço
valor
Para acessar o valor da variável a partir de um ponteiro que aponta para 
ela, utiliza-se o operador * junto à variável ponteiro (AGUILAR, 2008). No 
seguinte exemplo, *pIdade aponta para o valor da variável idade; e pIdade, 
para o seu endereço.
Uma vez que o ponteiro aponta para uma variável, qualquer modificação 
que for realizada nele refletirá nessa variável, pois ele é uma referência indireta 
à ela. No exemplo a seguir, modificou-se o conteúdo de idade para 35 por 
meio do ponteiro pIdade.
Um ponteiro pode, ainda, apontar para outro ponteiro, o que fará ambos 
se direcionarem ao endereço de memória da variável cujo primeiro ponteiro 
faz uma referência indireta.
Considerando que um array é uma estrutura de elementos homogêneos 
armazenados em sequência na memória e, também, que um ponteiro faz uma 
referência a um endereço de memória, pode-se percorrer um array por meio 
de incremento ou decremento de ponteiros (SILVA FILHO, 2010).
3Ponteiros e alocação dinâmica de memória
Isso é possível, porque um array disponibiliza o endereço do primeiro 
elemento armazenado na memória. Dessa forma, quando se incrementa um 
ponteiro, automaticamente, ele se posiciona no próximo elemento da estrutura, 
independentemente da quantidade de bytes que cada tipo de dado ocupa na 
memória (SILVA FILHO, 2010).
No exemplo a seguir, o ponteiro pNota recebe o endereço do primeiro ele-
mento do array nota. Perceba que a estrutura de repetição não utiliza o índice 
do array para imprimir seus elementos (Figura 2), pois eles são acessados por 
meio dos endereços de memória e do incremento do ponteiro a cada iteração.
Figura 2. Array de elementos na memória.
0x70fe30 0x70fe34 0x70fe38 0x70fe3c
7 9 8 10
Por ser um array de inteiros, cada elemento da estrutura ocupa um espaço 
de quatro bytes na memória. Como ele reserva apenas espaços contínuos, a 
varredura é possível por meio doincremento do ponteiro e parte da primeira 
posição.
Note, na Figura 2, que existe um acréscimo de quatro unidades (bytes) 
em cada posição da memória do array, pelos dois últimos dígitos de cada 
endereço: 0x70fe30, 0x70fe34, 0x70fe38 e 0x70fe3c. O último par tem uma 
letra, porque o endereço está apresentado em formato hexadecimal, cuja letra 
c indica o número 12.
Ponteiros e alocação dinâmica de memória4
Funcionamento da alocação dinâmica de 
memória
Como mencionado anteriormente, a declaração de variáveis reserva espaços 
endereçados na memória, e os ponteiros podem fazer referência a eles. No 
entanto, as declarações apresentadas utilizaram uma alocação estática de 
memória, pois suas variáveis foram declaradas pelo modo convencional, 
informando o tipo de dado e o seu nome. Ao utilizar variáveis estáticas, essa 
alocação ocorre no início da execução do programa, em que a quantidade 
de memória já é conhecida desde a fase de compilação para a criação do 
executável (AGUILAR, 2008).
Contudo, dessa forma, os programadores podem reservar mais memória do 
que o preciso, desperdiçando recursos desnecessariamente. Para resolver isso, 
a linguagem C++ fornece meios para alocar memória em tempo de execução, 
por meio da alocação dinâmica de memória (AGUILAR, 2008).
Na linguagem C, a alocação e a liberação dinâmicas de memória podem 
ser realizadas por meio das instruções memory allocation (malloc) e free, que 
reservam e liberam espaços na memória de acordo com a quantidade de bytes 
do tipo de dado utilizado (DEITEL; DEITEL, 2011).
Já a linguagem C++, além de permitir o uso das instruções malloc e free, 
fornece os operadores new e delete, os quais podem ser utilizados em objetos 
de diversos tipos, como dados primitivos, estruturas e classes, entre outros 
(VOTRE, 2016).
A seguir, você saberá mais sobre a alocação dinâmica por meio das ins-
truções malloc e free e, depois, pelos operadores new e delete.
Instruções malloc e free
Para utilizar as instruções malloc e free, é preciso incluir a biblioteca 
no programa, por meio da seguinte instrução:
A declaração de uma variável dinâmica deve ser realizada por meio de 
ponteiros, que fazem referência aos endereços de memória, os quais são 
reservados conforme a quantidade de bytes que o tipo de dados necessita.
A instrução sizeof pode ser utilizada para identificar a quantidade de 
bytes necessária de acordo com o tipo de dado utilizado. Veja no seguinte 
5Ponteiros e alocação dinâmica de memória
exemplo que o tratamento da variável ocorre pela manipulação de um ponteiro 
(DEITEL; DEITEL, 2011).
A liberação da memória reservada dinamicamente ocorre quando o pro-
grama é encerrado, descarregado da memória. No entanto, as variáveis alocadas 
de forma dinâmica podem ser liberadas durante a execução, por meio da 
instrução free (DEITEL; DEITEL, 2011).
A quantidade de bytes de cada tipo de dado pode variar de acordo com o sistema 
operacional utilizado. Há casos em que o tipo primitivo int pode ocupar dois ou quatro 
bytes, por isso, deve-se usar a instrução sizeof (DEITEL; DEITEL, 2011).
É possível, ainda, declarar arrays de forma dinâmica em tempo de execu-
ção. Para isso, multiplica-se o retorno de sizeof pelo número de elementos do 
array. Note que, apesar de o array nota ser um ponteiro, ele é tratado sem o 
operador *, pois possui um tratamento diferenciado.
Ponteiros e alocação dinâmica de memória6
O resultado da execução deste script apresenta o conteúdo de cada posição 
do array e o endereço de memória dos elementos.
Operadores new e delete
Os operadores new e delete foram implementados em C++ e, portanto, não 
funcionam em compiladores que suportam apenas a linguagem C (VOTRE, 
2016). Para apresentar a declaração de uma variável dinâmica em C++, utilizam-
-se as seguintes instruções.
Ou,
Ambas declaram uma variável chamada pIdade do tipo int e atribuem o 
valor 30, porém, a segunda instrução declara e inicializa em uma única linha. 
Além disso, nota-se que não é preciso usar a instrução sizeof, pois o operador 
new identifica o tamanho automaticamente (VOTRE, 2016).
Utilizam-se colchetes para declarar um array dinamicamente. O número 
entre eles indica a quantidade de elementos da estrutura (AGUILAR, 2008).
7Ponteiros e alocação dinâmica de memória
Implementação de um ponteiro
Para demonstrar a implementação de ponteiros em C++, você verá o de-
senvolvimento de um programa que sorteia 10 números entre 50 e 100 e 
os armazena em um array declarado dinamicamente. Na sequência, usa-se 
ponteiros para percorrer o array do início até o final e, depois, do final até o 
início, para imprimir os números e suas respectivas posições de memória. Por 
fim, apresenta-se o maior e o menor elementos, bem como suas respectivas 
posições de memória.
As linhas de 1 a 4 apresentam a inclusão das bibliotecas necessárias para 
gerar números aleatórios, a saída de dados e a declaração de uma constante 
chamada TOTAL, a qual contém o número máximo de elementos do array 
que será declarado.
A linha 6 apresenta a declaração de um array de ponteiros com alocação 
dinâmica chamado nota, que possui 10 elementos. Já as linhas de 7 a 10 
ilustram um laço de repetição, o qual produz e armazena números aleatórios 
entre 50 e 100 em cada posição do array, bem como imprime esses números 
e a sua respectiva posição de memória.
As linhas entre 11 e 14 declaram as variáveis que armazenarão o maior 
e o menor elementos, bem como as posições de memória de cada um. Esses 
elementos são armazenados em variáveis do tipo int; e seus endereços, em 
variáveis ponteiros do mesmo tipo.
Ponteiros e alocação dinâmica de memória8
Já nas linhas de 15 a 28, há uma estrutura de repetição que realiza 10 
iterações. No entanto, o array é percorrido pelo incremento de ponteiros, 
indicado pela linha 25, e não pelo contador do laço while. Isso é possível, 
porque ele disponibiliza o endereço do primeiro elemento na memória e, ao ser 
incrementado, posiciona-se automaticamente no endereço do próximo elemento.
Nessa estrutura de repetição, duas estruturas de controle identificam o maior 
e o menor elementos, bem como seus endereços, os quais são armazenados 
respectivamente nas variáveis maiorNotaEndereco e menorNotaEndereco.
Perceba que usa-se *nota para recuperar o conteúdo da posição do vetor 
(linhas 18 e 22) e apenas nota quando se deseja pegar o endereço da posição 
(linhas 19 e 23) ou incrementar o array (linha 25).
As linhas de 29 a 36 apresentam outra estrutura de repetição que realiza 
10 iterações, as quais servem de apoio para percorrer o array pelos endereços 
de memória, por ponteiros. No entanto, dessa vez, o array é percorrido de 
trás para frente.
Quando se percorre um array por ponteiros, um indicador registra a última 
posição acessada e o endereço é devolvido ao se realizar uma nova chamada 
do array. Como o trecho entre as linhas 16 e 27 o percorreu e incrementou 
seu endereço como último comando da estrutura while (linha 26), o ponteiro 
9Ponteiros e alocação dinâmica de memória
está acessando um endereço que ultrapassa os seus limites, o que é corrigido 
pela instrução nota-- (linha 29).
Ao posicionar o ponteiro na última posição do array, deve-se decrementar 
o ponteiro de nota, a cada iteração, até chegar ao seu início — esse decre-
mento é realizado pela instrução da linha 34. Já a variável cont serve apenas 
para controlar o contador de iterações da estrutura while, porém, ela não é 
utilizada para acessar os elementos do array, pois usam-se os ponteiros para 
essa finalidade.
Por fim, são apresentados o maior e o menor elementos em conjunto aos 
seus respectivos endereços de memória por meio da instrução cout. Na Figura 3, 
você pode ver o resultado da execução do programa.
Figura 3. Execução da implementação de ponteiros.
Ponteiros e alocação dinâmica de memória10
AGUILAR, L. J. Programação em C++: algoritmos, estruturas de dados e objetos. 2. ed. 
Porto Alegre: McGraw Hill, 2008.
DEITEL, P. J.; DEITEL, H.M. C: como programar. 6. ed. [São Paulo]: Pearson, 2011.
SILVA FILHO, A. M. Introdução à programação orientada a objetos com C++. Rio de 
Janeiro: Elsevier, 2010.
VOTRE, V. P. C++ explicado e aplicado. Rio de Janeiro: Alta Books, 2016.
Ponteiros e alocação dinâmica de memória11
 
Dica do professor
A linguagem C++ permite alocar memória dinamicamente, durante a execução de um programa. 
Essa alocação dinâmica é realizada por meio da instrução new, que reserva memória apenas quando 
o comando é executado, e não quando o programa é carregado pelo sistema operacional.
Assista, na Dica do Professor, como declarar um vetor em tempo de execução, a partir da alocação 
dinâmica de memória, e como percorrê-lo por meio de um ponteiro.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://fast.player.liquidplatform.com/pApiv2/embed/cee29914fad5b594d8f5918df1e801fd/40ca6c4d54edb217ec9dc09b2f76ffe6
Exercícios
1) Marque a alternativa correta em relação a uma variável ponteiro que vai armazenar o 
endereço de uma variável do tipo float.
A) Deve ser do tipo pointer, que significa tipo ponteiro.
B) Deve ser do tipo float, pois a variável a ser apontada é float.
C) Pode ser do tipo double, pois suporta o tipo float.
D) Pode ser de qualquer tipo, pois é um ponteiro.
E) Não possui um tipo definido, pois é um ponteiro.
2) Selecione a alternativa que apresenta corretamente a declaração de uma variável ponteiro 
chamada p, que recebe o endereço da variável chamada v, do tipo int, na linguagem C++:
A) int *p= &v.
B) int *p= *v.
C) int &p= v.
D) int &p= *v.
E) int &p= &v.
3) Marque a alternativa que apresenta corretamente a declaração de uma variável ponteiro 
com alocação dinâmica, na linguagem C++, que define um valor padrão na sua criação:
A) int x = new int.
B) int *x = new int.
C) int *x = new int (1).
D) int &x = new int (1).
Uma variável declarada como ponteiro deve ser do mesmo tipo da variável em que ela vai realizar o apontamento. Nesse caso, deve ser do tipo float.
A declaração de uma variável ponteiro, na linguagem C++, é realizada pela indicação do tipo de dado, do caractere * e do nome da variável. Quando recebe o endereço de outra variável, este deve ser indicado pelo caractere &.
Para declarar uma variável ponteiro com alocação dinâmica e definição de um valor padrão na sua criação, é preciso indicar que a variável é um ponteiro, por meio do asterisco, do uso da instrução new e de um valor entre parênteses após a definição do tipo.
E) int &x = new int = NULL.
4) Dado o seguinte algoritmo em C++, selecione a opção que apresenta a saída correta, ou seja, 
os valores que são armazenados no código:
int valor= 10;
int *inteiro= new int;
inteiro= &valor;
*inteiro= 15;
A) “inteiro” e “&inteiro” possuem o mesmo conteúdo.
B) “*inteiro” e “valor” possuem o mesmo conteúdo.
C) “inteiro” e “valor” possuem o mesmo conteúdo.
D) “&inteiro” e “&valor” possuem o mesmo conteúdo.
E) “inteiro” e “&valor” possuem o mesmo conteúdo.
5) Dado o seguinte algoritmo em C++, selecione a opção que apresenta a saída correta:
int valor= 10;
int *inteiro= new int(valor);
valor= 15;
A) valor é 10 e *inteiro é 10.
B) valor é 10 e *inteiro é 15.
C) valor é 15 e *inteiro é 10.
D) valor é 15 e *inteiro é 15.
E) valor é 15 e *inteiro é NULL.
A variável “*inteiro” é declarada como ponteiro do tipo int. Na sequência, esse ponteiro aponta para o endereço de “valor”. Assim, um ponteiro, ao ser acessado com o caractere *, faz referência à variável que ele aponta. Portanto, se modificamos o conteúdo da variável “valor”, automaticamente “*inteiro” possuirá o mesmo conteúdo.
Na prática
JP da Silva é desenvolvedor na empresa Sistemas Ultra Inteligentes SA há alguns anos. Dentre suas 
habilidades, destaca-se a sua facilidade de implementar rotinas que manipulam strings na linguagem 
de programação C++.
Para manipular strings, JP da Silva costuma usar ponteiros, por considerar que a execução é mais 
rápida e eficiente, pois, assim, ele consegue acessar diretamente os endereços de memória das 
variáveis e percorrer os caracteres de forma segura e ágil.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para 
acessar.
 
https://statics-marketplace.plataforma.grupoa.education/sagah/09174db9-a71a-40a1-84de-0d8c942b4e90/0c7811ca-790a-4c9e-b3ef-66aaa9892b31.jpg
Saiba +
Para ampliar o seu conhecimento a respeito desse assunto, veja abaixo as sugestões do professor:
Ponteiros - conceitos.
Assista ao vídeo a seguir para saber mais sobre introdução a ponteiros.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Ponteiros - operações.
Assista o vídeo a seguir para saber mais sobre operações com ponteiros.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Ponteiros com arrays.
Assista o vídeo a seguir para conhecer mais sobre ponteiros com arrays.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://www.youtube.com/embed/SJzd9x2S2yg
https://www.youtube.com/embed/cg1mnWupbTE
https://www.youtube.com/embed/w_BBUJWS-50

Mais conteúdos dessa disciplina