Você está na página 1de 51

Universidade Federal de Sergipe

Departamento de Sistemas de Informação

SINF0064 – Programação II


Prof. Dr. Alcides Xavier Benicasa
alcides@ufs.br

Roteiro

 Noções de referências/ponteiros.
Ponteiros
• Variáveis ponteiro
• Ponteiros e Funções

 Alocação dinâmica de memória


Vetores Dinâmicos
• Criando e usando
• Aritmética de ponteiros

2/102

1
Noções de
referências/ponteiros

Ponteiros

Introdução aos Ponteiros

 Definição de ponteiro:
Endereço de memória para uma variável

 Memória:
A memória é dividida em posições numeradas,
podendo ser endereços usados como nomes para
variáveis

 Você já usou ponteiros!


Argumentos/parâmetros chamados-por-referência
O endereço do argumento atual foi passado

4/102

2
Variáveis Ponteiro

 Ponteiros são ‘digitados’


Pode-se armazenar um ponteiro em uma variável
Não int, double, etc.
• Em vez disso: UM PONTEIRO para int, double, etc!

 Exemplo:
double *p;
p é declarado como um ‘ponteiro para a variável
double
Pode-se armazenar ponteiros para variável de tipo
double
Não para outros tipos!

5/102

Declarando Variáveis Ponteiro

 Ponteiros são declarados assim como outros


tipos?
Adicionar * antes do nome da variável
Gera um ‘ponteiro para’ aquele tipo

 ‘*’ deve estar antes de cada variável

 int *p1, *p2, v1, v2;


p1, p2 armazenam ponteiros para variáveis int
v1, v2 são variáveis comuns de tipo int

6/102

3
Apontar

 Terminologia e visão
Fale em ‘apontar’, não em ‘endereços’
Variável ponteiro ‘aponta para’ a variável comum

 Torna a visualização mais clara

7/102

Apontar para …

 int *p1, *p2, v1, v2;


p1 = &v1;
Faz a variável ponteiro p1 ‘apontar para’ a
variável int v1

 Operador, &
Diz respeito ao ‘endereço da’ variável

 Lê-se:
“p1 é igual ao endereço de v1”
ou “p1 aponta para v1”

8/102

4
Operadores * e &

 Lembre-se:
int *p1, *p2, v1, v2;
p1 = &v1;

 Agora temos dois modos de nos referirmos a v1:


A variável v1 propriamente dita:
printf(“%i\n”,v1);
Ou: cout << v1;
Através do ponteiro p1:
printf(“%i\n”,*p1);
Ou: cout << *p1;

 Operador de desreferenciação, *

 Variável ponteiro ‘desreferenciada’


Significa: “Obter dados para os quais p1 aponta”
9/102

Exemplo de ‘Apontar para’

 Considere:
int *p1, v1;
v1 = 0;
p1 = &v1;
*p1 = 42;
printf("%i\n",v1);
printf("%i\n",*p1);

 Gera a seguinte saída:


42
42

 p1 e v1 referem-se a mesma variável

10/102

5
Operador &

 O operador ‘de endereço’

 Também usado para especificar parâmetro


chamado-por-referência
Não é coincidência!
Lembre-se: parâmetros chamados-por-referência
passam o ‘endereço do’ argumento atual

 Os dois usos do operador estão intimamente


relacionados

11/102

Ponteiro: Atribuições

 Pode-se atribuir o valor de uma variável


ponteiro:
int *p1, *p2;
p2 = p1;
Atribui um ponteiro a outro
“Faz p2 apontar para onde p1 aponta”

 Não vá confundir com:


*p1 = *p2;
Não se está lidando com os ponteiros p1 e p2, e
sim com as variáveis para as quais os ponteiros
estão apontando

12/102

6
Gráfico de Atribuição de Ponteiros

13/102

O operador malloc

7
O Operador mallocCPuro

 Como um ponteiro pode se referir a uma variável…


Não é preciso ter um identificador padrão

 Podemos alocar variáveis dinamicamente


O operator malloc cria variáveis
• Nenhum identificador para referir-se à elas
• Somente um ponteiro!

 p1 = malloc (sizeof(int));
Cria uma variável nova ‘sem nome’ e atribui à p1 que
passa a ‘apontar para’ ela
Pode-se acessar com *p1
• O uso é exatamente igual às variáveis simples

15/102

Exemplo de Ponteiros – Exemplo 01 CPuro

16/102

8
Exemplo de Ponteiros – Exemplo 01 CPuro

17/102

Manipulações Básicas de Ponteiros: Gráfico

18/102

9
C++

O operador new

O Operador new

 Como um ponteiro pode se referir a uma variável…


Não é preciso ter um identificador padrão

 Podemos alocar variáveis dinamicamente


O operator new cria variáveis
• Nenhum identificador para referir-se à elas
• Somente um ponteiro!

 p1 = new int;
Cria uma variável nova ‘sem nome’ e atribui à p1 que
passa a ‘apontar para’ ela
Pode-se acessar com *p1
• O uso é exatamente igual às variáveis simples

20/102

10
Exemplo de Ponteiros – Exemplo 01 C/C++

21/102

Exemplo de Ponteiros – Exemplo 01 C/C++ (cont.)

22/102

11
Exemplo de Ponteiros – Exemplo 01 C/C++ (cont.)

23/102

Manipulações Básicas de Ponteiro: Gráfico

24/102

12
C/C++

Ponteiros e Funções

Ponteiros e Funções

 Ponteiros são tipos completos


Podem ser usados exatamente como outros tipos

 Podem ser parâmetros de funções

 Podem ser retornados por funções

 Exemplo:
int* encontreOutroPonteiro(int* p);
Esta declaração de função:
• Tem um ‘ponteiro para um’ parâmetro int
• Retorna ‘ponteiro para uma’ variável int

26/102

13
Exemplo de Ponteiros – Exemplo 02 CPuro

27/102

Manipulações Básicas de Ponteiros: Gráfico

28/102

14
Manipulações Básicas de Ponteiro: Gráfico

(h)
(j)
p1 = encontreOutroPonteiro(p2);
int *p3 = malloc (sizeof(int));
int* encontreOutroPonteiro(int* p)
*p3 = 50;
p p

p1 88 p1 88
p2 53 p2 10

p3 50

(i)
*p = 10; (k)
return p3;
p p1 = encontreOutroPonteiro(p2);

p1 88 p1 10

p2 10 p2 50

29/102

Alocação Dinâmica
de Memória

15
Alocação Dinâmica de Memória

 Uso da memória:

Memória
Estática
Código do Programa

Variáveis Globais e
Variáveis Estáticas

Variáveis Alocadas
Dinâmica
Memória

Dinâmicamente
(Memória Livre)

Variáveis Locais
(Pilha de Execução)
31/89

Alocação Dinâmica de Memória

 Uso da memória:

uso de variáveis globais (e estáticas):


• espaço reservado para uma variável global existe
enquanto o programa estiver sendo executado.

uso de variáveis locais:


• espaço existe apenas enquanto a função que declarou
a variável está sendo executada.
• liberado para outros usos quando a execução da
função termina.

32/102

16
Alocação Dinâmica de Memória

 Alocação Dinâmica:

espaço de memória é requisitada em tempo de


execução.

espaço permanece reservado até que seja


explicitamente liberado.

• depois de liberado, espaço estará disponibilizado para


outros usos e não pode mais ser acessado.

• espaço alocado e não liberado explicitamente, será


automaticamente liberado quando ao final da
execução.

33/102

Alocação Dinâmica de Memória

 Uso da memória:
alocação dinâmica de memória:
• usa a memória livre
• se o espaço de memória livre for menor que o espaço
requisitado, a alocação não é feita e o programa pode prever
tratamento de erro

pilha de execução:
• utilizada para alocar memória quando ocorre chamada de
função:
– sistema reserva o espaço para as variáveis locais da função
– quando a função termina, espaço é liberado (desempilhado)

• se a pilha tentar crescer mais do que o espaço disponível


existente, programa é abortado com erro

34/89

17
Alocação Dinâmica de Memória - Exemplo
int *p1;
p1 = new int;
Código do Programa
*p1 = 42;
int *p2; Variáveis Globais e
p2 = p1; Variáveis Estáticas

*p2 = 33;
p1 = new int; Variáveis Alocadas
Dinâmicamente
*p1 = 50; (Memória Livre)

Variáveis Locais
(Pilha de Execução)

35/102

Alocação Dinâmica de Memória - Exemplo


int *p1;
p1 = new int;
*p1 = 42;
int *p2;
p2 = p1;
*p2 = 33;
memória livre

p1 = new int;
*p1 = 50;
pilha

p1 ?

36/102

18
Alocação Dinâmica de Memória - Exemplo
int *p1;
p1 = new int;
*p1 = 42;
int *p2;
p2 = p1;
*p2 = 33;

memória livre
?
p1 = new int; 500

*p1 = 50;

pilha
p1 500

37/102

Alocação Dinâmica de Memória - Exemplo


int *p1;
p1 = new int;
*p1 = 42;
int *p2;
p2 = p1;
*p2 = 33;
memória livre

42
p1 = new int; 500

*p1 = 50;
pilha

p1 500

38/102

19
Alocação Dinâmica de Memória - Exemplo
int *p1;
p1 = new int;
*p1 = 42;
int *p2;
p2 = p1;
*p2 = 33;

memória livre
42
p1 = new int; 500

*p1 = 50;

pilha
p2 ?
p1 500

39/102

Alocação Dinâmica de Memória - Exemplo


int *p1;
p1 = new int;
*p1 = 42;
int *p2;
p2 = p1;
*p2 = 33;
memória livre

42
p1 = new int; 500

*p1 = 50;
pilha

p2 500
p1 500

40/102

20
Alocação Dinâmica de Memória - Exemplo
int *p1;
p1 = new int;
*p1 = 42;
int *p2;
p2 = p1;
*p2 = 33;

memória livre
33
p1 = new int; 500

*p1 = 50;

pilha
p2 500
p1 500

41/102

Alocação Dinâmica de Memória - Exemplo


int *p1;
p1 = new int;
*p1 = 42;
int *p2;
p2 = p1;
*p2 = 33;
memória livre

33
p1 = new int; ? 500
700
*p1 = 50;
pilha

p2 500
p1 700

42/102

21
Alocação Dinâmica de Memória - Exemplo
int *p1;
p1 = new int
*p1 = 42
int *p2;
p2 = p1;
*p2 = 33;

memória livre
33
p1 = new int; 50 500
700
*p1 = 50;

pilha
p2 500
p1 700

43/102

Verificando o Sucesso new

 Compiladores antigos:
Testam se NULL foi retornado pela chamada a new:

int *p;
p = new int;
if (p = = NULL)
{
cout << "Erro: Memória insuficiente.\n";
exit(1);
}
//Se new foi bem-sucedido, o programa
//continua a partir daqui.

44/102

22
new Bem-sucedida – Compilador Novo

 Compiladores mais novos:


Se a chamada new falhar:
• O programa termina automaticamente
• Produzindo uma mensagem de erro

 Ainda é uma boa prática usar a verificação de


NULL

45/102

Tamanho da Pilha (stack)

 Varia de uma implementação para outra

 Geralmente é grande
A maioria dos programas não utilizarão toda a
memória

 Gerenciamento de Memória
Ainda é uma boa prática
Princípio sólido de Engenharia de Software
A memória é finita
• independente de quanto se tenha!

46/102

23
Operador delete

 Desaloca memória dinâmica


Quando não é mais necessária
Devolve a memória ocupada pela variável dinâmica

Exemplo:
int *p;
p = new int(5);
… //processando…
delete p;

Desaloca memória dinâmica “apontada pelo ponteiro p”


Literalmente ‘destrói’ a variável dinâmica

47/102

Alocação Dinâmica de Memória – Exemplo (cont.)

int *p1;
p1 = new int
*p1 = 42
int *p2;
p2 = p1;
*p2 = 33;
memória livre

33
p1 = new int; 50 500
700
*p1 = 50;
delete p2;
delete p1;
pilha

p2 500
p1 700

48/102

24
Alocação Dinâmica de Memória – Exemplo (cont.)

int *p1;
p1 = new int
*p1 = 42
int *p2;
p2 = p1;
*p2 = 33;

memória livre
33
p1 = new int; 50 500
700
*p1 = 50;
delete p2;
delete p1;

pilha
p2 500
p1 700

49/102

Alocação Dinâmica de Memória – Exemplo (cont.)

int *p1;
p1 = new int
*p1 = 42
int *p2;
p2 = p1;
*p2 = 33;
memória livre

p1 = new int; 50
700
*p1 = 50;
delete p2;
delete p1;
pilha

p2 500
p1 700

50/102

25
Alocação Dinâmica de Memória – Exemplo (cont.)

int *p1;
p1 = new int
*p1 = 42
int *p2;
p2 = p1;
*p2 = 33;

memória livre
p1 = new int;
*p1 = 50;
delete p2;
delete p1;

pilha
p2 500
p1 700

51/102

Ponteiros Oscilantes

26
Ponteiros Oscilantes

 delete p;
Destrói a variável dinâmica
mas p ainda aponta para lá!
• Chamado ‘Ponteiro Oscilante’
Se p for então desreferenciado (*p)
• Resultados serão imprevisíveis!
• Freqüentemente desastrosos!

 Evite os ponteiros oscilantes


Fixe-os como NULL antes de desreferenciá-los:
delete p;
p = NULL;

53/102

Alocação Dinâmica de Memória – Exemplo (cont.)

int *p1;
p1 = new int
*p1 = 42
int *p2;
p2 = p1;
*p2 = 33;
memória livre

p1 = new int;
*p1 = 50;
delete p2;
delete p1;
pilha

p2 500
p1 = NULL; p1 700

p2 = NULL;
54/102

27
Alocação Dinâmica de Memória – Exemplo (cont.)

int *p1;
p1 = new int
*p1 = 42
int *p2;
p2 = p1;
*p2 = 33;

memória livre
p1 = new int;
*p1 = 50;
delete p2;
delete p1;

pilha
p2 500
p1 = NULL; p1 NULL

p2 = NULL;
55/102

Alocação Dinâmica de Memória – Exemplo (cont.)

int *p1;
p1 = new int
*p1 = 42
int *p2;
p2 = p1;
*p2 = 33;
memória livre

p1 = new int;
*p1 = 50;
delete p2;
delete p1;
pilha

p2 NULL
p1 = NULL; p1 NULL

p2 = NULL;
56/102

28
Variáveis Dinâmicas e Automáticas

 Variáveis Dinâmicas
Criadas com o operador new
Criadas e destruídas durante a execução do
programa

 Variáveis locais
Declaradas dentro de uma definição de função
Não-dinâmicas
• Criadas quando a função é chamada
• Destruídas quando a chamada de função é completada.
• Geralmente são chamadas de variáveis ‘automáticas’
• Propriedades controladas por você

57/102

Definindo Tipos Ponteiro

29
Definindo Tipos Ponteiro

 Pode-se definir um nome de tipo ponteiro de


modo que as variáveis ponteiros possam ser
declaradas como outras variáveis
Elimina a necessidade de colocar ‘*’ na declaração do
ponteiro

 typedef int* IntPtr;


Define um ‘novo tipo’ (alias)
Considere estas declarações:
IntPtr p;
int *p;
As duas são eqüivalentes

59/102

Exemplo de Ponteiros – Exemplo 03 C/C++


1. #include <iostream>
2. #include <locale.h>
3. using std::cout; using std::cin; using std::endl;

4. int main( )
5. {
6. setlocale (LC_ALL,"portuguese");
7. int tmp,a,b;

8. cout << "Informe o primeiro número: " << endl;


9. cin >> a;

10. cout << "Informe o segundo número: " << endl;


11. cin >> b;
Variável ocupando memória
12. tmp = a;
durante toda a “vida” da
13. a = b;
aplicação
14. b = tmp;

15. cout << "Depois da troca, primeiro número é " << a << " e o
segundo é " << b << endl;

16. return 0;
17. }
60/102

30
Exemplo de Ponteiros – Exemplo 03 C/C++ - Otimizando...
1. #include <iostream>
2. #include <locale.h>
3. using std::cout; using std::cin; using std::endl;

4. int main( )
5. {
6. setlocale (LC_ALL,"portuguese");
7. int a,b;
8. cout << "Informe o primeiro número: " << endl;
9. cin >> a;
10. cout << "Informe o segundo número: " << endl;
11. cin >> b;

12. int *tmp = new int;


13. *tmp = a;
Variável ocupando memória
14. a = b;
somente durante sua utilização
15. b = *tmp;
16. delete tmp;

17. cout << "Depois da troca, primeiro número é " << a << " e o
segundo é " << b << endl;

18. return 0;
19. }
61/102

Vetores Dinâmicos

31
Vetores Dinâmicos

 Variáveis vetores
Na verdade são variáveis ponteiros!

 Vetor-padrão
Tamanho fixo

 Vetor dinâmico
Tamanho não especificado quando se escreve o
programa
Determinado enquanto o programa é executado

63/102

Variáveis vetores

 Lembre-se: vetores são armazenados em endereços


de memória, seqüencialmente
A variável vetor ‘refere-se’ à 1ª variável indexada
Então a variável vetor é um tipo de variável
ponteiro!

 Exemplo:
int a[10];
int *p;
a e p são ambas variáveis ponteiro!

64/102

32
Variáveis Vetor  Ponteiros

 Lembre-se do exemplo anterior:


int a[10];
typedef int* IntPtr;
IntPtr p;

 a e p são variáveis ponteiro

 Podem atribuir:
p = a; // legal.
p agora aponta para onde a aponta
• Para 1a variável indexada do vetor a

a = p; // ilegal!

65/102

Variáveis Vetor  Ponteiros

 Variável vetor:
int a[10];
Porém, a variável a não é do tipo int*
E sim, “const int*”

 MAIS do que uma variável ponteiro


Neste caso, o vetor já estava alocado na memória
A variável a DEVE apontar pará lá…sempre!
• Não pode ser modificada! Pois é uma CONSTANTE!

 Em comparação com ponteiros simples


Os quais podem (e tipicamente) o fazem

66/102

33
Exemplo de Ponteiros – Exemplo 04 C/C++
#include <iostream>
using std::cout;
using std::endl;
typedef int* IntPtr;

int main( ) {
IntPtr p;
int a[10];
int index;

for (index = 0; index < 10; index++)


a[index] = index;

p = a;

for (index = 0; index < 10; index++)


cout << p[index] << " ";
cout << endl;

for (index = 0; index < 10; index++)


p[index] = p[index] + 1;

for (index = 0; index < 10; index++)


cout << a[index] << " ";
cout << endl; Diálogo Programa-Usuário
return 0; 0123456789
} 1 2 3 4 5 6 7 8 9 10
67/102

Vetores Dinâmicos

 Limitações dos Vetores


Precisa-se especificar o tamanho
Porém pode não ser conhecido até o programa ser
executado!
DEVE-SE ‘estimar’ o tamanho máximo necessário
Algumas vezes OK, outras NÃO
‘Gasto’ de memória

 Vetores Dinâmicos
Podem crescer e encolher conforme a necessidade

68/102

34
Criando Vetores Dinâmicos

 Muito simples!

 Use o operador new


Cria variáveis dinamicamente alocadas
Tratadas como vetores

 Exemplo:
typedef double* DoublePtr;
DoublePtr d;
d = new double[10];
Cria a variável vetor dinamicamente alocada d,
com dez elementos, tipo-base double

69/102

Apagando Vetores Dinâmicos

 Alocados dinamicamente em tempo de execução


Então devem ser apagados em tempo de execução

 Novamente Simples!

 Lembre-se do Exemplo:
d = new double[10];
… //Processando
delete [] d;
Desaloca toda a memória para o vetor dinâmico
Os colchetes indicam que o ‘vetor’ existe
Lembre-se: d ainda aponta para lá!
Deve-se fixar d = NULL;

70/102

35
Exemplo de Ponteiros – Exemplo 05 C/C++
#include <iostream>
using std::cin;
using std::cout;

typedef int* IntPtr;

void fillArray(int b[], int size);


int search(int c[], int size, int target);

int main( ) {
cout << "Este programa efetua uma busca em uma lista de números.\n";

int arraySize;
cout << "Quantos números haverá na lista? ";
cin >> arraySize;
IntPtr a;
a = new int[arraySize];

fillArray(a, arraySize);

int target;
cout << "Digite um valor a ser procurado: ";
cin >> target;
int location = search(a, arraySize, target);
if (location == -1)
cout << target << " não está no vetor.\n";
else
cout << target << " é o elemento " << location << " no vetor.\n";

delete [] a;

return 0;
} 71/102
//...

Exemplo de Ponteiros – Exemplo 05 C/C++ (cont.)


//...
void fillArray(int b[], int size)
{
cout << "Digite " << size << " inteiros.\n";
for (int index = 0; index < size; index++)
cin >> b[index];
}

int search(int c[], int size, int target)


{
int index = 0;
while ((c[index] != target) && (index < size))
index++;
if (index == size)
index = -1;
return index;
}
Diálogo Programa-Usuário
Este programa efetua uma busca em uma lista de números.
Quantos números haverá na lista? 5
Digite 5 inteiros.
12345
Digite um valor a ser procurado: 3
72/102
3 é o elemento 2 no vetor.

36
Funções que retornam um vetor

 Não é permitido que um tipo vetor seja


retornado por uma função.

 Exemplo:
int[] umaFuncao( ); //ILEGAL

 Em vez disso retorne um ponteiro para o tipo-


base do vetor:
int* umaFuncao( ); //Legal

73/102

Exemplo de Ponteiros – Exemplo 06 C/C++


#include <iostream> //..
using std::cout;
using std::endl; int* doubler(int c[], int size)
{
int* doubler(int a[], int size); int* temp = new int[size];

int main( ) { for (int i = 0; i < size; i++)


int a[] = {1, 2, 3, 4, 5}; temp[i] = 2*c[i];
int* b;
return temp;
b = doubler(a, 5); }

int i;
cout << "Vetor a:\n";
for (i = 0; i < 5; i++)
cout << a[i] << " ";
cout << endl;

cout << "Vetor b:\n";


for (i = 0; i < 5; i++)
cout << b[i] << " ";
cout << endl; Diálogo Programa-Usuário
delete[] b; Vetor a:
return 0; 12345
} Vetor b:
//.. 2 4 6 8 10
74/102

37
Aritmética de Ponteiros

 Pode-se efetuar um tipo de aritmética de ponteiros.

 Aritmética de ‘endereços’

 Exemplo:
typedef double* DoublePtr;
DoublePtr d;
d = new double[10];
d contém o endereço de d[0]
d + 1 calcula o endereço de d[1]
d + 2 calcula o endereço de d[2]

75/102

Manipulação Alternativa de Vetores

 Use a aritmética de ponteiros!

 ‘Atravesse’ o vetor sem indexar:


for (int i = 0; i < tamanhoDoVetor; i++)
cout << *(d + i)<< " ";

 Equivale a:
for (int i = 0; i < tamanhoDoVetor; i++)
cout << d[i] << " ";

 Somente adição/subtração com ponteiros


Não se pode multiplicar nem dividir

 Pode-se usar ++ e –- com ponteiros

76/102

38
Vetores Dinâmicos Multidimensionais

 Sim, nós podemos!

 Lembre-se: ‘vetor de vetores’

 Uma Definição de tipo ajuda a ‘vê-los’:

typedef int* IntVetorPtr;


IntVetorPtr* m = new IntVetorPtr[3];

Cria um vetor de 3 ponteiros


• Cada um dos quais pode nomear um vetor dinâmico de ints

 for (int i = 0; i < 3; i++)


m[i] = new int[4];

O resultado m é um vetor dinâmico de três por quatro.

77/102

Exemplo de Ponteiros – Exemplo 07 C/C++


#include <iostream> using std::cin; using std::cout; using std::endl;

typedef int* IntArrayPtr;

int main( ) {
int d1, d2;
cout << "Informe as dimensões linha e a coluna do vetor:\n";
cin >> d1 >> d2;

IntArrayPtr *m = new IntArrayPtr[d1];


int i, j;
for (i = 0; i < d1; i++)
m[i] = new int[d2];

cout << "Digite " << d1 << " linhas de "


<< d2 << " inteiros cada:\n";
for (i = 0; i < d1; i++)
for (j = 0; j < d2; j++)
cin >> m[i][j];

cout << "Ecoando o vetor bidimensional:\n"; Diálogo Programa-Usuário


for (i = 0; i < d1; i++) {
for (j = 0; j < d2; j++) Informe as dimensões linha e a coluna do vetor:
cout << m[i][j] << " "; 34
cout << endl; Digite 3 linhas de 4 inteiros cada:
} 1234
5678
for (i = 0; i < d1; i++) 9012
delete[] m[i]; Ecoando o vetor bidimensional:
delete[] m; 1234
5678
return 0; 9012
}78/102

39
Alocação Dinâmica de Memória – Bidimensionais

typedef int* IntPtr;

memória livre
pilha
79/102

Alocação Dinâmica de Memória – Bidimensionais

typedef int* IntPtr;


int a[3];
111
0
1
2
memória livre
pilha

a 111

80/102

40
Alocação Dinâmica de Memória – Bidimensionais

typedef int* IntPtr;


int a[3];
a[0]=1;a[1]=4;a[2]=3;
111
0 1
1 4
2 3

memória livre
pilha
a 111

81/102

Alocação Dinâmica de Memória – Bidimensionais

typedef int* IntPtr;


int a[3];
a[0]=1;a[1]=4;a[2]=3;
IntPtr p; 0
111
1
1 4
2 3
memória livre
pilha

p ?
a 111

82/102

41
Alocação Dinâmica de Memória – Bidimensionais

typedef int* IntPtr;


int a[3];
a[0]=1;a[1]=4;a[2]=3;
IntPtr p; 0
111
1
p = a; 1
2
4
3

memória livre
pilha
p 111
a 111

83/102

Alocação Dinâmica de Memória – Bidimensionais

typedef int* IntPtr;


int a[3];
a[0]=1;a[1]=4;a[2]=3;
IntPtr p; 0
111
1
p = a; 1
2
4
9
memória livre

p[2] = 9;
pilha

p 111
a 111

84/102

42
Alocação Dinâmica de Memória – Bidimensionais

typedef int* IntPtr;


int a[3]; 222
a[0]=1;a[1]=4;a[2]=3; 0
1
IntPtr p; 0
111
1
2

p = a; 1
2
4
9

memória livre
p[2] = 9;
p = new int[3];

pilha
p 222
a 111

85/102

Alocação Dinâmica de Memória – Bidimensionais

typedef int* IntPtr;


int a[3]; 222
a[0]=1;a[1]=4;a[2]=3; 0
1
8
1
IntPtr p; 0
111
1
2 32

p = a; 1
2
4
9
memória livre

p[2] = 9;
p = new int[3];
p[0]=8;p[1]=1;p[2]=32;
pilha

p 222
a 111

86/102

43
Alocação Dinâmica de Memória – Bidimensionais

typedef int* IntPtr;


int a[3]; 222
a[0]=1;a[1]=4;a[2]=3; 0
1
8
1
IntPtr p; 0
111
1
2 32

p = a; 1
2
4
9

memória livre
p[2] = 9;
p = new int[3];
p[0]=8;p[1]=1;p[2]=32;
IntPtr* m;

pilha
m ?
p 222
a 111

87/102

Alocação Dinâmica de Memória – Bidimensionais

typedef int* IntPtr;


int a[3]; 222
a[0]=1;a[1]=4;a[2]=3; 0
1
8
1
IntPtr p; 0
111
1
2 32

p = a; 1
2
4
9
memória livre

p[2] = 9;
p = new int[3];
p[0]=8;p[1]=1;p[2]=32;
333
IntPtr* m; 0 ?
1 ?
m = new IntPtr[2];
pilha

m 333
p 222
a 111

88/102

44
Alocação Dinâmica de Memória – Bidimensionais

typedef int* IntPtr;


int a[3]; 222
a[0]=1;a[1]=4;a[2]=3; 0
1
8
1
IntPtr p; 0
111
1
2 32

p = a; 1
2
4
9

memória livre
p[2] = 9;
p = new int[3];
p[0]=8;p[1]=1;p[2]=32;
333
IntPtr* m; 0 111
1 222
m = new IntPtr[2];
m[0] = a; m[1] = p;

pilha
m 333
p 222
a 111

89/102

Alocação Dinâmica de Memória – Bidimensionais

typedef int* IntPtr;


int a[3]; 222
a[0]=1;a[1]=4;a[2]=3; 0
1
8
1
IntPtr p; 0
111
1
2 32

p = a; 1
2
4
9
memória livre

p[2] = 9;
p = new int[3];
p[0]=8;p[1]=1;p[2]=32;
333
IntPtr* m; 0 111
1 222
m = new IntPtr[2];
m[0] = a; m[1] = p;
pilha

m 333
p 222
a 111

90/102

45
Alocação Dinâmica de Memória – Bidimensionais

typedef int* IntPtr;


int a[3]; 222
a[0]=1;a[1]=4;a[2]=3; 0
1
8
1
IntPtr p; 0
111
1
2 32

p = a; 1
2
4
68

memória livre
p[2] = 9;
p = new int[3];
p[0]=8;p[1]=1;p[2]=32;
333
IntPtr* m; 0 111
1 222
m = new IntPtr[2];
m[0] = a; m[1] = p;

pilha
m 333
p 222
m[0][2] = 68; a 111

91/102

Alocação Dinâmica de Memória – Bidimensionais

222
0 8
1 1
111
2 32
0 1
1 4
2 68
memória livre

333
0 111
1 222
pilha

m 333
p 222
a 111

92/102

46
Exemplo de Ponteiros – Exemplo 08 C/C++
#include <iostream> #include <stdio.h>
typedef int* IntPtr;
int main( )
{
int a[3];
a[0]=1;
a[1]=4;
a[2]=3;
IntPtr p;
p = a;
printf("[%i,%i,%i]\n",a[0],a[1],a[2]); printf("[%i,%i,%i]\n",p[0],p[1],p[2]);
p[2] = 9;
printf("\n[%i,%i,%i]\n",a[0],a[1],a[2]); printf("[%i,%i,%i]\n",p[0],p[1],p[2]);
p = new int[3];
p[0]=8; p[1]=1; p[2]=32;
printf("\n[%i,%i,%i]\n",a[0],a[1],a[2]); printf("[%i,%i,%i]\n\n",p[0],p[1],p[2]);
IntPtr* m;
m = new IntPtr[2];
m[0] = a; m[1] = p;
for (int i=0; i<2; i++)
printf("[%i,%i,%i]\n",m[i][0],m[i][1],m[i][2]);
m[0][2] = 68;
for (int i=0; i<2; i++)
printf("[%i,%i,%i]\n",m[i][0],m[i][1],m[i][2]);

printf("\n[%i,%i,%i]\n",a[0],a[1],a[2]); printf("[%i,%i,%i]\n",p[0],p[1],p[2]);

for (int i=0; i<2; i++)


delete[] m[i];
delete[] m; m = NULL; p = NULL;
return 0;
}
93/102

Exemplo de Ponteiros – Exemplo 08 C/C++


Diálogo Programa-Usuário

94/102

47
Alocação Dinâmica de Memória – Bidimensionais

for (int i=0; i<2; i++)


delete[] m[i]; 222
0 8
1 1
111
2 32
0 1
1 4
2 68

memória livre
333
0 111
1 222

pilha
m 333
p 222
a 111

95/102

Alocação Dinâmica de Memória – Bidimensionais

for (int i=0; i<2; i++)


delete[] m[i]; 222
0 8
1 1
111
2 32
0 1
1 4
2 68
memória livre

m[0]
333
0 111
1 222
pilha

m 333
p 222
a 111

96/102

48
Alocação Dinâmica de Memória – Bidimensionais

for (int i=0; i<2; i++)


delete[] m[i]; 222
0 8
1 1
111
2 32
0 1
1 4
2 3

memória livre
m[1]
333
0 111
1 222

pilha
m 333
p 222
a 111

97/102

Alocação Dinâmica de Memória – Bidimensionais

for (int i=0; i<2; i++)


delete[] m[i];
delete[] m; 111
0 1
1 4
2 3
memória livre

333
0 111
1 222
pilha

m 333
p 222
a 111

98/102

49
Alocação Dinâmica de Memória – Bidimensionais

for (int i=0; i<2; i++)


delete[] m[i];
delete[] m; 111

m = NULL; 0
1
1
4
2 3

memória livre
pilha
m NULL
p 222
a 111

99/102

Alocação Dinâmica de Memória – Bidimensionais

for (int i=0; i<2; i++)


delete[] m[i];
delete[] m; 111

m = NULL; 0
1
1
4
p = NULL; 2 3
memória livre
pilha

m NULL
p NULL
a 111

100/102

50
Alocação Dinâmica de Memória – Bidimensionais

111
0 1
1 4
2 3

memória livre
pilha
m NULL
p NULL
a 111

101/102

Referências

 SAVITCH, Walter J. C++ Absoluto. Tradução Claudia


Martins. 1.ed - São Paulo: Addison Wesley, 2004.

 Stroustrup, Bjarne. The C++ Programming Language,


Special Edition.

 Eckel, Bruce. Thinking in C++, 2nd ed. Volume 1.

 Agradecimentos:
Notas de Aula de Gustavo e Luiz Felipe Sotero do curso de
C/C++ do CIn.

102/102

51

Você também pode gostar