"Wyjaśnij w jaki sposób przechowywane są dane typu `String` w pamięci komptuera".
(dla sprecyzowania: chodzi o typ `String` z Pascala; w innych językach nie wiem jak to się nazywa i czy działa w ten sam sposób).
Prawdę mówiąc, dotychczas tylko korzystałem z dobrodziejstw typu `String` i mało obchodziło mnie to, w jaki sposób te dane przetrzymywane są w pamięci.
No i cóż - doszło do tego, że jutro muszę to wytłumaczyć.
Na początku obstawiałem, że są to ciągłe dane (coś jak PChar, tylko nie zakończone na #0, a długość mają zapisaną gdzieś indziej).
No ale skoro `String` może przetrzymywać dane do 2 GiB, to moja teza raczej odpada, ponieważ skąd w pamięci wytrzasnąć wolne ciągle 2 GiB?
Może lista? No ale przecież wtedy jeden znak zajmowałby przynajmniej 5 bajtów (4 bajty na wskaźnik do następnego, 1 bajt to znak).
Proszę o pomoc i najlepiej w miarę dokładne wytłumaczenie.
" Life is not a problem to be solved but a reality to be experienced! "
© Copyright 2013 - 2024 KUDO.TIPS - All rights reserved.
Pascalowy "Short String" składa się z bajta w którym zapisana jest długość i maksymalnie 255 bajtów w których zapisany zostaje napis.
string z C++, UnicodeString z pascala działają podobnie, przechowywana jest długość napisu (jako liczba 32 bitowa na systemach 32 bitowych lub 64 bitowa na systemach 64 bitowych i cały napis jako tablica). W C++ oprócz długości przechowywana jest także pojemność napisu (która może być większa od długości napisu, gdyż w trakcie doklejania pojedynczych znaków do stringa alokuje się więcej pamięci aby odwoływać się przy każdym dodaniu znaku do managera pamięci).
String zawsze przechowywane jest jako ciągły napis (tablica).
null terminated string (czyli Twoje pascalowe PChar), to wskaźnik na pierwszy znak napisu, który kończy się znakiem "\0".
W czasach DOSa występował potworek w którym stosowano obie konwencje, czyli -1 bajt to długość, a po tym następuje null terminated string. Ale to zamierzchła historia.
W C++ występował kiedyś typ danych "rope" (gdzieś w okolicach STL w implementacji od SGI lub g++ w wersji 2.7.2) ale odszedł w niepamięć. W tym typie danych napis był reprezentowany jako lista tablic, dzięki temu wstawianie czegoś w środek było tanią operacją. Podobnie do tego typu danych działa klasa StringBuffer z języka Java.
2 GiB jako rozmiar null terminated string traktuj umownie. 2GiB to maksymalna ilość pamięci którą może dostać jeden proces na systemie 32 bitowym. (pomijam odpalanie windowsa z opcją /3GB).
Pamiętaj, że te 2GiB są do wyłączniej dyspozycji procesu. Proces nie widzi obszarów udostępnionych innym procesom, dzieje się tak, gdyż układ zarządzania pamięcią (MMU) procesora, we współpracy z systemem operacyjnym dokonuje mapowania pamięci i pokazuje procesowi wirtualny obraz, w którym istnieje obszar zarezerwowany dla systemu operacyjnego, dla urządzeń WeWy i ciągły obszar dla procesu, a nie obszar poszatkowany przez obszary zajmowane przez inne procesy.
Z ciekawostek:
W pascalu shortstring i ansistring mają po jednym bajcie na znak.
W c++ string ma 1 bajt na znak, a wstring 4 bajty na znak (pod Linuxem), a wstring 2 bajty na znak pod windows.