Jest to drugi po menedżerze bloków pamięci dostępny standardowo menedżer pamięci, jednak innego rodzaju. Przydziela on obiekt tablicy “E_mem_Q_tab”, który przechowuje nieliniowo w pamięci listę bloków, np. struktur języka C. Każdy z tych bloków ma identyfikator przechowywany w zmiennej typu I. Można tworzyć w tablicy nowe bloki, wyrzucać istniejace oraz wyliczać wszystkie w pętli.
Tablice zarządzane przez tego menedżera służą do przechowywania kolekcji obiektów wydawanych w czasie wykonywania się programu z innych menedżerów po identyfikatorze.
Obiekty tablicy tworzy się i wyrzuca następującymi procedurami:
struct E_mem_Q_tab_Z * E_mem_Q_tab_M( N u , I n ); void E_mem_Q_tab_W( struct E_mem_Q_tab_Z *tab );
Procedura tworzenia obiektu bierze parametry: rozmiar obiektu tablicy oraz początkową liczbę obiektów. W przypadku niepowodzenia wraca ona z wartością 0, a w przeciwnym przypadku podaje adres obiektu tablicy.
Procedurami narzędziowymi można sprawdzić
- ‣ czy element o identyfikatorze jest w tablicy, procedurą “E_mem_Q_tab_T”
- ‣ liczbę elementów w tablicy, procedurą “E_mem_Q_tab_R_n”
- ‣ oraz odczytać adres bloku danych elementu tablicy, procedurą “E_mem_Q_tab_R”
Natomiast nowe elementy w tablicy można tworzyć procedurami:
I E_mem_Q_tab_I_add( struct E_mem_Q_tab_Z *tab ); I E_mem_Q_tab_I_add_i( struct E_mem_Q_tab_Z *tab , I id );
Przy czym druga procedura dodaje element z podanym identyfikatorem, więc musi on być nie używany przed jej wywołaniem.
Elementy tablicy można wyrzucić procedurą:
N E_mem_Q_tab_I_rem( struct E_mem_Q_tab_Z *tab , I id );
Iteratory
Menedżer tablic obsługuje też obiekty iteratorów dwóch rodzajów:
- • statyczne “E_mem_Q_tab_Z_iter”
- • obiektowe “E_mem_Q_tab_Q_iter”
Statyczne
Pierwsze mają zastosowanie wtedy, gdy pomiędzy wyliczeniami takiego iteratora nie następuje przełączenie zadania, a drugie – wtedy, gdy takie przełączenie może nastąpić (oczywiście przy użyciu instrukcji przełączenia zadania).
Do wyliczania w pętli iteratorów statycznych istnieją instrukcje wbudowane “for_each”:
for_each( zmienna_identyfikatora, adres_obiektu, nazwa_obiektu ){} for_each_( zmienna_identyfikatora, adres_obiektu, nazwa_obiektu ){}
Druga z nich korzysta z już zdefiniowanej zmiennej identyfikatora.
Natomiast do wyliczania obiektu z pominięciem elementu o podanym identyfikatorze:
for_each_out( ominięty_identyfikator, zmienna_identyfikatora, adres_obiektu, nazwa_obiektu ){} for_each_out_( ominięty_identyfikator, zmienna_identyfikatora, adres_obiektu, nazwa_obiektu ){}
W przypadku obiektu tablicy opisywanego w tym wpisie instrukcje wyliczania w pętli iteratora statycznego mają następującą przykładową postać:
for_each( id, tab, E_mem_Q_tab ){} for_each_out( out, id, tab, E_mem_Q_tab ){}
Są również procedury wyliczania iteratora od końca do początku:
for_each( zmienna_identyfikatora, adres_obiektu, nazwa_obiektu ){} for_each_( zmienna_identyfikatora, adres_obiektu, nazwa_obiektu ){} for_each_rev_out( ominięty_identyfikator, zmienna_identyfikatora, adres_obiektu, nazwa_obiektu ){} for_each_rev_out_( ominięty_identyfikator, zmienna_identyfikatora, adres_obiektu, nazwa_obiektu ){}
Obiektowe
Natomiast iteratory obiektowe wymagają utworzenia obiektu iteratora i jego wyrzucenia po użyciu procedurami:
I E_mem_Q_tab_Q_iter_M( struct E_mem_Q_tab_Z *tab , I out_id ); void E_mem_Q_tab_Q_iter_W( struct E_mem_Q_tab_Z *tab , I iterator_id );
Procedura tworząca iterator bierze jako parametr identyfikator pomijanego elementu i wraca z identyfikatorem iteratora obiektowego albo wartością ~0 w przypadku niepowodzenia.
W każdym przypadku jako pomijany element można podać wartość ~0, kiedy to żaden element nie zostanie pominięty.
Kolejne elementy tablicy wylicza się procedurą:
I E_mem_Q_tab_Q_iter_R_next( struct E_mem_Q_tab_Z *tab , I iterator_id , I id );
Koniec wyliczania jest sygnalizowany wartością ~0 zwróconą jako identyfikator kolejnego elementu.
Na przykład:
I iter_id = E_mem_Q_tab_Q_iter_M( tab, ~0 ); I id = ~0; while( !~( id = E_mem_Q_tab_Q_iter_R_next( iter_id, id )) { I_B() break; } E_mem_Q_tab_Q_iter_W( tab, iter_id );