Este é um recurso de programação interessante, podemos ter ponteiros apontando para ponteiros. Abaixo um pequeno exemplo em Pascal / Delphi de como é a declaração e o uso de um ponteiro que aponta para um ponteiro:
{$APPTYPE CONSOLE}
uses SysUtils;
type
PInteger = ^Integer;
PPInteger = ^PInteger;
var
p: PInteger;
pp: PPInteger;
begin
New(p);
try
pp := @p;
p^ := 5;
WriteLn(Format(
‘pp:%p, p:%p, pp^:%p, p^:%d, pp^^:%d’,
[pp, p, pp^, p^, pp^^]));
finally
Dispose(p);
end;
ReadLn;
end.
Ao executarmos este programa, teremos o seguinte resultado:
pp:0040A600, p:00CF0870, pp^:00CF0870, p^:5, pp^^:5
pp foi definido como PPInteger, que pela declação type é um ponteiro de PInteger. p aponta para endereço de memória alocado por New, mas o próprio p é uma variável que contém um endereço, o endereço desta variável que contém o endereço pode ser obtido por @p. Por isso a declação pp := @p; não pega o endereço alocado por New e sim o endereço que o compilador reservou para a variável p. Prá lá de confuso!
Para ajudar na explicação, vou aproveitar e citar um artigo do HowStuffWorks e fazer um paralelo.
Ponteiros para ponteiros
É possível e freqüentemente útil criar ponteiros de ponteiros. Esta técnica é às vezes chamada de handle e é útil em certas situações nas quais o sistema operacional precisa da capacidade de mover blocos de memória na pilha a seu critério. O exemplo a seguir demonstra um ponteiro de ponteiro:
int *q;
p = (int **)malloc(sizeof(int *));
*p = (int *)malloc(sizeof(int));
**p = 12;
q = *p;
printf("%d\n", *q);
free(q);
free(p);
Um paralelo com o Pascal / Delphi temos:
{$APPTYPE CONSOLE}
uses SysUtils;
type
PInteger = ^Integer;
PPInteger = ^PInteger;
var
p: PPInteger;
q: PInteger;
begin
New(p);
New(p^);
try
p^^ := 12;
q := p^;
WriteLn(q^);
finally
Dispose(q);
Dispose(p);
end;
ReadLn;
end.
O Windows e o Mac OS usam esta estrutura para permitir a consolidação de memória na pilha. O programa administra o ponteiro p, enquanto o sistema operacional administra o ponteiro *p. Uma vez que o sistema operacional gerencia *p, o bloco apontado por *p (**p) pode ser movido e *p pode ser alterado para refletir a transferência sem afetar o programa que utiliza p. Os ponteiros de ponteiros também são freqüentemente usados em C para identificar parâmetros de ponteiros em funções.
0 Respostas para “Ponteiros no Pascal / Delphi - Ponteiro de Ponteiro”
Deixe uma Resposta