Pokud v IDL vytváříme struktury (záznamy), jejichž položky jsou pole, často stojíme před problémem, že velikost těchto polí musí být fixní (tj. určená v okamžiku vzniku struktury).
;příklad - struktura se skalarem a poli 1x10 a 2x3 X={a: 1L, b:Fltarr(10), c:Dblarr(2,3)}
Pokud chceme do položky c nyní uložit např. pole celých čísel o pěti prvcích, musíme znovu do X uložit celou strukturu:
;příklad - struktura se skalarem a poli 1x10 a 1x5 X={a: X.a, b:X.b, c:Intarr(5)}Tento způsob je při větším počtu položek nebo jejich vnoření nepraktický a navíc funguje jen pro anonymní struktury. Správnou metodou je využití ukazatelů jako zvláštního typu proměnných vytvářených na hromadě (dalším podobným typem jsou ještě objekty). Obsahem proměnné typu ukazatel přitom není adresa paměti, ale index do vnitřních tabulek IDL. Proto je práce s ukazateli v IDL celkem bezpečná - při nesprávném programování dochází nejvýše k pozvolnému úniku volné paměti, která však může být reaktivována. Uvedený příklad řešený pomocí ukazatelů naleznete na konci této kapitoly.
IDL ve skutečnosti vytváří všechny proměnné na hromadě, jejich identifikátory však představují přímé odkazy. O alokaci a dealokaci paměti se v pozadí stará manažer hromady. Přiřazením nového obsahu do proměnné se zároveň vyhradí potřebné místo v paměti a případně se uvolní původní, nyní již nepotřebné. To se samozřejmě neděje, pokud přiřazujeme jen do části proměnné (do určité položky struktury, do podmnožiny buněk pole).
Funkce Temporary(P) poskytne obsah proměnné P v parametru, po té paměť alokovanou proměnné P uvolní a její identifikátor se stane nedefinovaným. Takto obvykle uvolňujeme již nepotřebná data, která zabírají hodně místa v paměti.
;příklad - G a H jsou velká pole
G=0 ;radikální zmenšení alokované paměti pro G, proměnná G je stále definována> x=Total(Temporary(H)) ;při posledním použití dealokace paměti H
Používáme-li ukazatele, závisí alokace a dealokace částečně na nás. Proměnné na hromadě musíme umět vytvořit a uschovat odkazy na ně, musíme umět testovat platnost těchto odkazů a s jejich pomocí pracovat s obsahem proměnných. Nakonec musíme umět proměnné na hromadě zrušit, včetně těch, na které se odkazy nedopatřením ztratily. Následující body shrnují používané funkce a procedury a uvádějí příklady:
;příklad - nový ukazatel na kopii pole 2x3 pole=Bytarr(2,3) ppole=Ptr_new(pole)
;příklad - nový ukazatel na pole 2x3 pole=Bytarr(2,3) ppole=Ptr_new(pole, /no_copy)
;příklad - nový ukazatel na nedefinovanou proměnnou ppole=Ptr_new(/allocate_heap) *ppole=Bytarr(1000) ;příklad 2 - obdobně pracují příkazy ; (je-li A nedefinovaná proměnná, jinak po prvním příkazu ukazuje qpole na kopii A) qpole=Ptr_new(A) *qpole=Dblarr(10,20)
;příklad - null ukazatel ppole=Ptr_new()
;příklad - dereference při čtení hodnoty a=*ppole(0,0) print, *ppole
;příklad - dereference v přiřazení (*ppole)(0,*)=Bindgen(3) *ppole=Replicate(255, 2,3)
;příklad - dereference null ukazatele je neplatná ptrnull=Ptr_new() *ptrnull=Strarr(10) ;za běhu způsobí chybu
;příklad - práce s polem ukazatelů xpole=Ptrarr(10) xpole(0)=Ptr_new(Indgen(20)) Plot, *xpole(0) (*xpole(0))(0:2)=[3, 4, 5] *xpole(1)=10.5 ; dereference null ukazatele, za běhu způsobí chybu
;příklad 2 - práce s polem ukazatelů xpole=Ptrarr(10, /allocate_heap) *xpole(0)=Indgen(20) Plot, *xpole(0) Print, N_elements(*xpole(4)) *xpole(9)=0
;příklad - zrušení proměnných *ppole a *xpole(0) až *xpole(9) Ptr_free, ppole, xpole
;test platnosti ukazatele ppole if Ptr_valid(ppole) then ... ;vytvoření seznamu indexů platných ukazatelů v poli xpole ii=Where(Ptr_valid(xpole), cii)
;seznam všech proměnných na hromadě u=Ptr_valid() ;zrušení všech proměnných na hromadě (nerekurzivní, nedoporučuje se) Ptr_free, Ptr_valid()
;vytvoření proměnné a ukazatele t=Ptr_new([0,1,2,1,0]) ;vytiskneme číslo proměnné na hromadě a obsah proměnné Print, t, *t ... ;ztracení ukazatele, pole stále zůstává na hromadě t=200 ... ;obnovení ukazatele na pole v hromadě, víme-li, že jde o proměnnou hromady číslo 1 t=Ptr_valid(1, /cast)
;vyčištění paměti Heap_GC, /ptr
;vytvoření složité struktury s odkazy y={a:0, b:Ptr_new(Indgen(100))} X={Temporary(y), f:Ptrarr(2)} X.f(0)=Ptr_new(Fltarr(100,100)) X.f(1)=Ptr_new(Ptr_new(Strarr(500))) ... ;řízené vyčištění paměti obsazené proměnnými hromady s odkazy v X Heap_free, X, /ptr
;příklad - struktura se skalárem, polem 1x10 a obecným typem dat X={a: 1L, b:Fltarr(10), c:Ptr_new(/allocate_heap)} ;do položky c uložíme pole 2x3 *X.c=Dblarr(2,3)} ... ;do položky c uložíme pole 1x5 *X.c=Intarr(5)}
L.Přech,
poslední úpravy 6.2.2004