Hlavní navigace

GLib: Bleskové operace s pamětí (3)

Michal Burda 16. 5. 2000

V minulých dílech jsme si ukázali, jak s knihovnou GLib urychlit alokace paměti použitím tzv. Memory Chunks. Dnes se zaměříme na využití tohoto mechanizmu při dynamické alokaci řetězců.

GMemChunk

y jsou jistě v mnoha případech užitečné. Jejich problém však spočívá v tom, že všechny prvky (atomy) musí být stejné velikosti. Tím se vylučuje použití Chunků při práci s řetězci, protože každý řetězec může být obecně proměnné délky.

Tento nedostatek vyplňuje knihovna GLib funkcemi kolem datového typu GStringChunk. Než se pustíme do dalšího výkladu, připomeňme jen v krátkosti použitou terminologii. „Chunkem“ nazývám úsek paměti, skládající se z několika bloků stejné velikosti. Do něj se pak místo alokace dynamicky umisťují nové proměnné, prvky Chunku zvané „atomy“ (viz. předchozí díl).

GStringChunk

GStringChunk 

Do GStringChunk u je možno přidávat řetězce různé délky. Není však možno jednotlivé řetězce z Chunku dealokovat – musíte dealokovat vždy celý GStringChunk.

Struktura:

struct GStringChunk; 

reprezentuje řetězcový Chunk. Práce s ní by měla být realizována výhradně následujícími funkcemi.

GStringChunk* g_string_chunk_new(gint size); 

…vytvoří nový GStringChunk a vrátí pointer na něj. Argument size je implicitní velikost bloku. Je-li třeba do GStringChunk u u­ložit řetězec delší než tato implicitní hodnota, bude pro něj alokován větší blok paměti.

Pro vkládání (neboli kopírování) řetězců do chunku slouží dvě funkce:

gchar* g_string_chunk_insert(GStringChunk *chunk,
                             const gchar *string);

a

gchar* g_string_chunk_insert_const(GStringChunk *chunk,
                                   const gchar *string);

Funkce g_string_chun­k_insert() přidá kopii řetězce string do GStringChunk u chunk. Vrátí pointer na tuto kopii. Znaky vráceného řetězce mohou být měněny. Neměli byste však, jako obvykle, zapisovat za konec tohoto řetězce.

Oproti ní, funkce g_string_chunk_insert_const() nejprve prohledá GStringChunk chunk na výskyt řetězce string. Nalezne-li takový, a byl-li do chunk u navíc přidán právě funkcí g_string_chunk_insert_const(), vrátí pointer na něj. Jinak string do chunk u zkopíruje a vrátí pointer. Tato funkce je užitečná v případech, kdy hodláte do GStringChunk u při­dávat mnoho konstantních řetězců a nechcete příliš plýtvat místem. Budete-li používat výhradně g_string_chunk_insert_const(), vloží se každý řetězec do GStringChunk u pou­ze jednou – v dalších pokusech se bude vracet pouze pointer na tento již uložený řetězec. Na to však musíte pamatovat. V programu se může vyskytovat několik pointerů na jeden řetězec – jakýkoliv zápis do takového řetězce musí být potom proveden velmi opatrně.

Je třeba poznamenat, že g_string_chunk_insert_const() nikdy nevrátí pointer na řetězec, který byl do GStringChunk u při­dán funkcí g_string_chun­k_insert(), i kdyby se shodovaly.

g_string_chunk_insert() 
void g_string_chunk_free(GStringChunk *chunk); 

…uvolní veškerou paměť alokovanou GStringChunk em chunk. Po vykonání této funkce již není bezpečné přistupovat k řetězcům, které původně obsahovala.

Příklad:

/* ukazka pouziti GStringChunk */
#include<glib.h>
gint main(void)
{
  GStringChunk *chunk;
  gchar *s1, *s2, *s3;

  /* vytvoreni noveho chunku */
  chunk = g_string_chunk_new(50);

  /* vkladani retezcu do chunku */
  s1 = g_string_chunk_insert(chunk, RETEZEC);
  s2 = g_string_chunk_insert_const(chunk, RETEZEC);
  s3 = g_string_chunk_insert_const(chunk, RETEZEC);

  /* Po techto operacich budou v chunku dva retezce "Ahoj svete!" */
  /* Na prvni bude ukazovat s1 a na druhy s2 a s3 spolecne (viz   */
  /* nasledujici vypis adres)                                     */

  printf("Adresa s1: %p\nAdresa s2: %p\nAdresa s3: %p\n", s1, s2, s3);

  /* uvolneni GStringChunku z pameti */
  g_string_chunk_free(chunk);

  return(0);
}

Po spuštění tohoto ukázkového programu by se měly vypsat adresy tří řetězců uložených do chunku. Adresa prvního řetězce by se měla od ostatních dvou lišit; adresy druhého a třetího řetězce však musí být stejné. Jak je to možné?

Všechny tři řetězce obsahují stejný text definovaný makrem RETEZEC. První řetězec, s1, se do chunku přidává jako první a navíc funkcí g_string_chun­k_insert()  – kopírování jistě proběhne.

Po něm se alokuje řetězec s2, ovšem funkcí g_string_chunk_insert_const()  – provede se prohledání chunku na řetězec RETEZEC, ale bezvýsledně: žádný takový do chunku funkcí g_string_chunk_insert_const() ještě přidán nebyl (je lhostejné, že už tam ve skutečnosti je alokovaný funkcí g_string_chun­k_insert()).

Nakonec se alokuje řetězec s3. Voláním funkce g_string_chunk_insert_const() se znovu prohledá celý chunk – tentokrát se však nalezne řetězec s2. Funkce tento pointer vrátí – s3 tedy bude ukazovat na fyzicky stejný řetězec jako  s2

Našli jste v článku chybu?
Vitalia.cz: „Připluly“ z Německa a možná obsahují jed

„Připluly“ z Německa a možná obsahují jed

Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

Podnikatel.cz: K EET. Štamgast už peníze na stole nenechá

K EET. Štamgast už peníze na stole nenechá

Vitalia.cz: Říká amoleta - a myslí palačinka

Říká amoleta - a myslí palačinka

DigiZone.cz: Česká televize mění schéma ČT :D

Česká televize mění schéma ČT :D

Měšec.cz: Zdravotní a sociální pojištění 2017: Připlatíte

Zdravotní a sociální pojištění 2017: Připlatíte

120na80.cz: Pánové, pečujte o svoje přirození a prostatu

Pánové, pečujte o svoje přirození a prostatu

Vitalia.cz: Tesco: Chudá rodina si koupí levné polské kuře

Tesco: Chudá rodina si koupí levné polské kuře

Vitalia.cz: Jsou čajové sáčky toxické?

Jsou čajové sáčky toxické?

120na80.cz: Jak oddálit Alzheimera?

Jak oddálit Alzheimera?

DigiZone.cz: ČT má dalšího zástupce v EBU

ČT má dalšího zástupce v EBU

DigiZone.cz: Sony KD-55XD8005 s Android 6.0

Sony KD-55XD8005 s Android 6.0

Podnikatel.cz: Prodává přes internet. Kdy platí zdravotko?

Prodává přes internet. Kdy platí zdravotko?

120na80.cz: Rakovina oka. Jak ji poznáte?

Rakovina oka. Jak ji poznáte?

Měšec.cz: Kdy vám stát dá na stěhování 50 000 Kč?

Kdy vám stát dá na stěhování 50 000 Kč?

DigiZone.cz: NG natáčí v Praze seriál o Einsteinovi

NG natáčí v Praze seriál o Einsteinovi

Vitalia.cz: To není kašel! Správná diagnóza zachrání život

To není kašel! Správná diagnóza zachrání život

Vitalia.cz: Paštiky plné masa ho zatím neuživí

Paštiky plné masa ho zatím neuživí

Měšec.cz: Finančním poradcům hrozí vracení provizí

Finančním poradcům hrozí vracení provizí

Podnikatel.cz: Na poslední chvíli šokuje vyjímkami v EET

Na poslední chvíli šokuje vyjímkami v EET