Hlavní navigace

GLib: Pole (2)

Michal Burda

Pracovat s automaticky rostoucími poli jsme se naučili v minulém díle. Dnes nás čeká další výklad o polích knihovny GLib - tentokrát o speciálních polích pointerů.

GPtrArray

slouží výhradně k uchovávání pointerů. Funkce pro práci s ním jsou velmi podobné funkcím pro práci s poli GArray a jelikož jsme si mechanizmus automaticky rostoucích polí popsali důkladně v minulém díle, dnes funkce pro práci s GPtrArray  proletíme trochu rychleji. Jejich činnost je totiž vcelku analogická.

Pole pointerů GPtrArray je definováno strukturou

struct GPtrArray
{
  gpointer *pdata;
  guint     len;
};

Jak asi očekáváte, pdata je samotné pole pointerů a můžete s ním pracovat jako s obyčejným céčkovským polem. Nemůžete se však spolehnout, že se pole bude vyskytovat vždy na stejné adrese v paměti. S tím, jak pole roste, se také realokuje a tedy i jeho umístění se mění. Položka len obsahuje aktuální počet prvků v poli.

Vytvoření pole GPtrArray

Nové pole pointerů se vytvoří (alokuje) zavoláním funkce

GPtrArray* g_ptr_array_new(void); 

Přidávání položek do pole GPtrArray

void g_ptr_array_add(GPtrArray *array, gpointer data); 

…tato funkce přidá pointer data na konec pole array. Jinými slovy, na konci pole array se vytvoří nová položka, do které se zkopíruje adresa uložená v argumentu data.

void g_ptr_array_set_size(GPtrArray *array, gint length); 

…nastaví velikost pole array na hodnotu length položek. array se podle potřeby zvětší. Nové položky budou nastaveny na  NULL.

Odstraňování položek z GPtrArray

Odstraněním položky z pole GPtrArray se docela často změní indexy některých dalších položek. Budete-li tedy s poli kromě vkládání provádět také výmaz položek, nemůžete spoléhat na to, že daná položka pole bude mít po celou dobu stejný index.

gboolean g_ptr_array_remove(GPtrArray *array, gpointer data); 

Odstraní první výskyt pointeru data v pointerovém poli array. Funkce vrátí TRUE, jestliže byl pointer odstraněn, nebo FALSE jestliže pointer data nebyl v poli nalezen. Položky pole, které se nacházejí za odstraňovaným pointerem data, budou posunuty tak, aby vyplnily vzniklou mezeru.

gpointer g_ptr_array_remove_index(GPtrArray *array, guint index); 

…z pole array odstraní pointer s indexem index. Zbývající položky budou posunuty tak, aby vyplnily vzniklou mezeru.

gboolean g_ptr_array_remove_fast(GPtrArray *array, gpointer data); 

…tato funkce dělá v podstatě totéž, co funkce g_ptr_array_re­move(): z pole array odstraní první výskyt prvku data a v případě úspěchu vrátí TRUE. Její rozdíl však spočívá v tom, že do mezery vzniklé odstraněním prvku z pole přesune poslední prvek pole – operace tak proběhne rychleji, než v případě posouvání všech zbývajících prvků. Nevýhoda však spočívá v tom, že tato metoda nezachovává pořadí prvků v poli.

gpointer g_ptr_array_remove_index_fast(GPtrArray *array, guint index); 

…odstraní index-tou položku pole array a na její místo přesune poslední prvek pole. Funkce g_ptr_array_remove_fast() sice proběhne rychleji než její obdoba g_ptr_array_re­move(), její nevýhodou však je, že nezachovává pořadí prvků.

Odkazování se na položky pole GPtrArray

Přístup k položkám pole můžete uskutečňovat použitím položky pdata struktury GPtrArray, nebo můžete s výhodou používat následující makro:

#define g_ptr_array_index(array,index) 

…které vrátí index-tý prvek pole array. O způsobech práce s makrem tohoto typu jsem psal v minulém díle, proto se nebudu opakovat.

Uvolnění GPtrArray z paměti

Nakonec, až ukončíte s GPtrArray  práci, musíte jej jako obvykle dealokovat:

void g_ptr_array_free(GPtrArray *array, gboolean free_seg); 

…tato funkce dealokuje pole array a je-li navíc parametr free_seg nastaven na TRUE, dealokuje i data v tomto poli uložená. Je-li naopak free_seg rovno FALSE, dealokuje se pouze struktura reprezentující pole array, ale data v paměti zůstanou a po skončení musí být dealokovány zvlášť (voláním  g_free()).

A to je dnes vše. Příště si ukážeme práci s poli bajtů ( GByteArray).

Našli jste v článku chybu?