Lección 9 · 9 de 20
Punteros, New y Dispose · Pascal
Trabaje con punteros en Pascal: direcciones con @, acceso con ^, y memoria dinámica reservada con New y devuelta con Dispose.

Un puntero guarda la dirección de un dato, no el dato. PProduct = ^TProduct declara un puntero a TProduct, y PInteger ya viene definido en la RTL. Por convención, los tipos puntero empiezan por P.
`@units` obtiene la dirección de una variable que ya existe, y `pUnits^` sigue el puntero hasta el dato. Por eso pUnits^ := pUnits^ + 5 cambia la propia units, que pasa de 10 a 15. La salida nunca muestra direcciones: cambian en cada ejecución y no dicen nada útil.
`New(item)` reserva en el montón (*heap*) un TProduct nuevo y deja su dirección en item; además inicializa los campos gestionados como Name. A partir de ahí se trabaja con item^.Name e item^.Stock. Restock recibe el puntero y modifica el registro original, no una copia.
`Dispose(item)` devuelve esa memoria. Lo que se reserva con New se libera con Dispose, exactamente una vez; si se olvida, hay una fuga. Después conviene poner el puntero a `nil` para no usar por error una dirección liberada, y `Assigned` comprueba si apunta a algo.
Los objetos de las lecciones anteriores son, por dentro, punteros: Create y Free hacen el papel de New y Dispose. Saber cómo funcionan ayuda a entender por qué asignar un objeto copia solo la referencia.
Código · main.pas
program main;type TProduct = record Name: String; Stock: Integer; end; PProduct = ^TProduct; // a pointer to a TProductprocedure Restock(item: PProduct; amount: Integer);begin Inc(item^.Stock, amount); // changes the record it points toend;var units: Integer; pUnits: PInteger; item: PProduct;begin units := 10; pUnits := @units; // the address of an existing variable pUnits^ := pUnits^ + 5; // ^ follows the pointer WriteLn('units = ', units); item := nil; WriteLn('Assigned before New: ', Assigned(item)); New(item); // a new record on the heap item^.Name := 'Printer toner'; item^.Stock := 3; Restock(item, 12); WriteLn(item^.Name, ': ', item^.Stock, ' in stock'); Dispose(item); // give the memory back item := nil; // and forget the old address WriteLn('Assigned after Dispose: ', Assigned(item));end.Salida · fpc main.pas && ./main
units = 15 Assigned before New: FALSE Printer toner: 15 in stock Assigned after Dispose: FALSE
Para recordar
@xes la dirección dex;p^es el dato al que apuntap.Newreserva memoria en el montón;Disposela devuelve.- Cada
Newnecesita exactamente unDispose. - Tras
Dispose, ponga el puntero anil. Assigned(p)dice sipapunta a algo.
Ejercicio
Cree con New un segundo producto, 'Paper A4' con 40 unidades, escriba la suma de las existencias de los dos y libere ambos con Dispose.