Karakterfüzér

A Programozás Wiki wikiből
(PChar (adattípus) szócikkből átirányítva)

A karakterfüzér (vagy más néven string ill. karakterlánc) egy karakterek sorozatának tárolására alkalmas adattípust jelöl. A string típusok belső ábrázolási módja és ezzel összefüggésben maximális hossza és egyéb korlátai platformonként és nyelvenként erősen eltérhetnek.

Ábrázolási módok[szerkesztés]

Null-terminált karakterfüzér[szerkesztés]

A null-terminált ábrázolási módban - mint neve is mutatja - a karakterlánc végét egy ASCII 0 karakter jelöli. Ebben az ábrázolási módban a stringre egy mutatóval lehet hivatkozni, amely a füzér első karakterére mutat; a további karakterek - egészen a lezáró ASCII 0 karakterig - egymás után, bájtfolytonosan helyezkednek el a memóriában.

A karakterek null-terminált formátumban történő ábrázolása nem teszi lehetővé ASCII 0 karakterek ábrázolását a karakterfüzérben - így nem alkalmas pl. tetszőleges bináris fájl tartalmának tárolására - , a füzér hossza pedig csak annak teljes végigvizsgálásával állapítható meg, ami jelentősen megnövelt futásidőt jelenthet az ennél hatékonyabb ábrázolási módokhoz képest.

A null-terminált ábrázolás egyik legnagyobb veszélye, hogy az általa foglalt memória mérete alapesetben nem rögzített. Ha a programozó nem elég körültekintő, bizonyos esetekben speciális bemenettel (akár egy program felületén is) a karakterfüzér "túlírható", azaz a részére allokált memóriaterület végén túlra vonatkozó írási - esetleg olvasási - művelet is kiváltható. Ez más adatok tárolására fenntartott területek tartalmának sérüléséhez, és ezen keresztül a program hibás működéséhez vezethet, illetve bizonyos esetekben és célzott módodon történő kiváltás esetén alkalmas lehet a program által végrehajtott utasítások befolyásolására, meghatározására is, külsőleg meghatározott kód injektálását lehetővé téve a programba. Ezt a jelenséget puffertúlcsordulásnak (buffer overflow) nevezzük, és a legelterjedtebb programozási hibák egyike.

Megjegyzés: Nemcsak a nullás kódú karakter lehet stringterminátor, például a CP/M (és a MS-DOS), 9-es funkciója egy dollárjellel('$') lezárt stringet ír a standard outputra.

Pascal string[szerkesztés]

Pascal-ban - és a Pascal string-et másoló nyelvekben - a string egy olyan adattípust takar, amely a füzér elemeit alkalmazó karakterek mellett azok számát - azaz a string hosszát - is külön nyilvántartja, a memóriában általában az első karaktert megelőző pozíció(ko)n. Ez jóval fejlettebb módszer a null-terminált típusú ábrázolásnál, hiszen nem csak bármely karakterkód - beleértve az ASCII 0 - ábrázolását teszi lehetővé a füzérben, de a füzér hosszának megállapításához sem igényli annak végigvizsgálását, amely jelentősen gyorsítja a programok futását.

Kombinált hossztárolás[szerkesztés]

Egyes nyelvekben (pl. Delphi) a Pascal-stílusú karakterfüzér után még kötelezően tárolnak egy 0 karaktert is, amely nem számít bele a füzér hosszába. Ez a megoldás amellett, hogy megtartja a Pascal string előnyeit, null-terminált karakterfüzérként is olvasható, így át lehet adni olyan programkódnak, amely csak ezt a formát képes kezelni. Fontos, hogy az így kapott null-terminált füzért csak olvasni biztonságos, mert írás esetén a megváltozott hossz nem tárolódna el a Pascal string hossz mezejében.

Ábrázolási hossz[szerkesztés]

A karakterfüzérekben ábrázolható karakterek száma implementációnként jelentősen eltérhet. Az eredeti Pascal nyelvben a karakterfüzérek fordítási időben definiált, fix hosszúsággal rendelkeztek - ez a megközelítés azonban rugalmatlan és elavultnak tekinthető. Ehelyett a modern programozási nyelvek változó hosszúságú karakterfüzérek használatát támogatják, amelyek hossza nulla és egy fordítási időben meghatározott ill. a típus sajátosságaiból eredő felső korlát között szabadon változhat. A Pascal 8- és 16-bites változataiban a karakterfüzérek maximális hossza jellemzően 255 karakter volt, a 32-bites fordítóknál azonban ez a korlát a 64KB-ot vagy akár a 2GB-ot is elérheti.

Referencia-számolt karakterfüzérek[szerkesztés]

Egyes nyelvekben (pl. Delphi) a string referencia-számolt típust képez, amely azt jelenti, hogy érték szerinti átadása, változók közötti másolása során nem kerül a füzér ténylegesen lemásolásra a memóriában, mindössze a string referenciaszámlálója kerül megnövelésre eggyel, a változó vagy hivatkozás megsemmisülése vagy más karakterfüzérre állítása esetén pedig csökkentésre. A karakterfüzér által elfoglalt helyet a memóriában ekkor a futásidejű könyvtár akkor szabadítja fel, ha a referenciaszámláló értéke nullára csökken, azaz az összes hivatkozás megszűnésén keresztül a string elérhetetlenné válik a továbbiakban a program számára. A karakterfüzér lemásolása a memóriában kizárólag akkor történik meg, ha annak elemeit valamelyik érték szerinti hivatkozási helyen módosítja az ottani vagy az onnan meghívott kód (lásd copy-on-write) - ilyenkor utóbbi művelet végrehajtása előtt egy identikus másolat készül a memóriában, és a módosító művelet már ezen hajtódik végre, az eredeti füzértartalmat érintetlenül hagyva. Ez ugyanakkor cím szerinti átadásnál értelemszerűen nem érvényes, hiszen ott minden esetben az eredeti karakterfüzér kerül módosításra.

Karakterek kódolása[szerkesztés]

Az internet térnyerésével egyre nagyobb igény jelentkezett olyan eszközökre, amik a különféle nyelvek speciális karaktereit is támogatják. A karakterfüzérek esetén korábban csak az adott ország karaktertáblájával kódolt szövegek jelentek meg megfelelően. Fejlettebb megoldások például a kódolás megnevezésének tárolása (html, email), széles (2 bájtos) karakterek használata, vagy változó szélességű kódolás alkalmazása (utf8). A fejlesztői eszközökben a különféle ábrázolási módok között többnyire könyvtári függvények segítségével lehet váltani.