Typická paměťová reprezentace programu C se skládá z následujících částí.
-
Textový segment (text segment) — tj. instrukce procesoru
-
Inicializovaný datový segment (data segment)
-
Segment neinicializovaných dat (bss)
-
Halda (heap)
-
Zásobník (stack)
-
text: Textový segment, také známý jako kódový segment nebo jednoduše text, je jednou z částí programu v objektovém souboru nebo v paměti, která obsahuje spustitelné instrukce. Jako oblast paměti může být textový segment umístěn pod haldu nebo zásobník, aby se zabránilo přepsání haldami a přetečeními zásobníku. Obvykle je textový segment sdílený, takže pro často spouštěné programy, jako jsou textové editory, kompilátor C, shelly a tak dále, může být v paměti pouze jedna kopie textového segmentu. Textový segment je také často pouze pro čtení, aby se zabránilo programu náhodně upravit jeho instrukce.
-
data: Inicializovaný datový segment, obvykle nazývaný jednoduše datový segment. Datový segment je část virtuálního adresového prostoru programu, která obsahuje globální proměnné a statické proměnné, které jsou inicializovány programátorem. Všimněte si, že datový segment není jen pro čtení, protože hodnoty proměnných lze za běhu měnit. Tento segment lze dále klasifikovat do inicializované oblasti pouze pro čtení a inicializované oblasti pro čtení a zápis. Například globální řetězec definovaný pomocí char s[] = „hello world“ v C a příkaz C jako int debug=1 mimo hlavní (tj. globální) by byly uloženy v inicializované oblasti čtení a zápisu. A globální příkaz C jako const char string = „hello world“ způsobí, že řetězec bude doslova „hello world“ uložen v inicializované oblasti pouze pro čtení a řetězec proměnné ukazatele znaků v inicializované oblasti pro čtení a zápis. Příklad: statické int i = 10 bude uloženo v datovém segmentu a globální int i = 10 bude také uloženo v datovém segmentu
-
bss: Neinicializovaný datový segment často nazývaný „bss“ segment, pojmenovaný po prastarém operátoru assembleru, který znamenal „blok zahájený symbolem“. Data v tomto segmentu jsou inicializována jádrem na 0 předtím, než program začne spouštět neinicializovaná data začínající na konci datového segmentu a obsahuje všechny globální proměnné a statické proměnné, které jsou inicializovány na nulu nebo nemají explicitní inicializaci ve zdrojovém kódu. Například proměnná deklarovaná jako static int i; by byly obsaženy v segmentu BSS. Například globální proměnná deklarovaná int j; by byly obsaženy v segmentu BSS.
-
stack: Oblast zásobníku tradičně sousedila s oblastí haldy a rostla v opačném směru; když se ukazatel zásobníku setkal s ukazatelem haldy, volná paměť byla vyčerpána. (S moderními velkými adresovými prostory a technikami virtuální paměti mohou být umístěny téměř kdekoli, ale stále obvykle rostou v opačných směrech.) Oblast zásobníku obsahuje zásobník programů, strukturu LIFO, obvykle umístěnou ve vyšších částech paměti. Na standardní počítačové architektuře PC x86 roste směrem k nulové adrese; na některých jiných architekturách roste v opačném směru. Registr „ukazatel zásobníku — stack pointer“ sleduje horní část zásobníku; upraví se pokaždé, když je hodnota „vtlačena — push“ do zásobníku. Sada hodnot posunutých pro jedno volání funkce se nazývá „rámec zásobníku — stack frame“; Rámec zásobníku se skládá minimálně z návratové adresy. Zásobník, kde se ukládají automatické proměnné spolu s informacemi, které se ukládají při každém volání funkce. Při každém volání funkce se do zásobníku uloží adresa, kam se vrátit, a určité informace o prostředí volajícího, jako jsou některé registry stroje. Nově volaná funkce pak alokuje místo na zásobníku pro své automatické proměnné. Takto mohou fungovat rekurzivní funkce v C. Pokaždé, když se rekurzivní funkce volá sama sebe, je použit nový zásobníkový rámec, takže jedna sada proměnných neinterferuje s proměnnými z jiné instance funkce.
-
heap: Halda je segment, kde obvykle probíhá dynamická alokace paměti. Oblast haldy začíná na konci segmentu BSS a odtud roste na větší adresy. Oblast haldy je spravována malloc(), realloc() a free(), které mohou k úpravě své velikosti používat systémová volání brk a sbrk (všimněte si, že použití brk/sbrk a jediné „oblasti haldy“ není nutné ke splnění kontraktu malloc/realloc/free; mohou být také implementovány pomocí mmap k rezervaci potenciálně nesouvislých oblastí virtuální paměti do virtuálního adresového prostoru procesu). Oblast haldy je sdílena všemi sdílenými knihovnami a dynamicky načítanými moduly v procesu.
| Takhle je to na Linuxu na architektuře x86 a x86_64, kde je k dispozici VMM (virtual memory management) na úrovni OS a MMU (memory management unit) v hardware procesoru. Na Raspberry Pi Pico to bude malinko jinak, protože procesor RP2040 MMU nemá. |