1. Index
  2. Shell
  3. C
  4. POSIX
  5. JavaScript

Arbeitsspeicher

Der Adressraum auf einem typischen Linux-System hat folgenden Aufbau:

32-Bit 64-Bit Rechte Segment Beschreibung
0000:0000 0000:0000:0000 ----
0804:8000 0000:0040:0000 r-xp TEXT Programmcode und Konstanten


brk

RLIMIT_DATA
0000:0060:0000 r--p DATA Initialisierte globale Variablen
rw-- BSS Null-initialisierte globale Variablen
rw-p HEAP Dynamische Speicherverwaltung

rwxp MMAP Memory Mapped Files
(Shared Memory & Libraries)
RLIMIT_STACK

sp

rw-- STACK Lokale Variablen
Rücksprungadresse und Parameter
rw-p CMD Kommandozeilenargumente
rw-- ENV Umgebungsvariablen
c000:0000 8000:0000:0000 --xp KERNEL Kernel Space

stddef.h

#define NULL ((void *) 0) Zeiger nach Nirgendwo
#define offsetof (type, member) Position eines Felds in der Struktur
typedef size_t unsigned int Größe von Objekten im Speicher
typedef rsize_t unsigned int Dito aber mit garantierter Bereichsprüfung
typedef ptrdiff_t Abstand innerhalb eines Objekts
typedef wchar_t unsigned short 16 Bit Unicode
typedef errno_t int Rückgabewert für Funktionen die errno liefern

string.h

void * memset (void * s, int c, size_t n) Speicherbereich mit Zeichen füllen
void * memfrob (void * s, size_t n) Speicherbereich mit XOR 42 behandeln
void * memcpy (void * dest, const void * src, size_t n) Disjunkten Speicherbereich kopieren
void * memccpy (void * dest, const void * src, int c, size_t n) Dito, aber bei einem bestimmten Zeichen stoppen
void * mempcpy (void * dest, const void * src, size_t n) Dito, Zeiger auf das Ende des Zielspeichers liefern
void * memmove (void * dest, const void * src, size_t n) Überlappenden Speicherbereich kopieren
void * memchr (const void * s, int c, size_t n) Zeichen im Speicherbereich suchen
void * memrchr (const void * s, int c, size_t n) Dito, von hinten her
void * rawmemchr (const void * s, int c) Optimal, wenn das Zeichen garantiert vorkommt
int memcmp (const void * s1, const void * s2, size_t n) Speicherbereiche vergleichen
void * memmem (const void * haystack, size_t haystacklen, const void * needle, size_t needlelen)

stdlib.h

Speicher auf dem Heap reservieren und freigeben.

void * malloc (size_t size) Reservieren
void * calloc (size_t nmemb, size_t size) Initialisieren
void * realloc (void * ptr, size_t size) Vergrößern
void free (void * ptr) Freigeben
void * valloc ( size_t size) Seitenanfang
void * aligned_alloc ( size_t alignment, size_t size) Zweierpotenz
int posix_memalign (void ** memptr, size_t alignment, size_t size) Zweierpotenz

malloc.h

Einblick in die dynamische Speicherverwaltung

struct mallinfo
int arena Speicher im nicht-mmap Bereich
int ordblks Anzahl freier Blöcke
int smblks Anzahl freier Fastbin Blöcke
int hblks Anzahl per mmap eingebelendeter Bereiche
int hblkhd Speicher im mmap Bereich
int usmblks Maximal belegter Speicher
int fsmblks Speicher in freien Fastbin Blöcken
int uordblks Gesamter belegter Speicher
int fordblks Gesamter freier Speicher
int keepcost Oberster freigebbarer Speicher
struct mallinfo mallinfo (void) Gibt Einblick in die dynamische Speicherverwaltung

sys/mman.h

Memory Mapping wird verwendet, um (Teile von) Dateien in den Adressraum des Prozesses einzublenden.

void *mmap ( void * addr, size_t len, int prot, int flags,
int fd, off_t offset)
int munmap ( void * addr, size_t len)
int mprotect ( void * addr, size_t len, int prot)
int msync ( void * addr, size_t len, int flags)
int mlock (const void * addr, size_t len)
int munlock (const void * addr, size_t len)
int mlockall ( int flags)
int munlockall (void)
int mincore ( void * addr, size_t len, unsigned char * vec)
void * mremap ( void * addr, size_t len, size_t new_len, int flags)
int remap_file_pages ( void * addr, size_t len, int prot,
ssize_t pgoff, int flags)
int madvise ( void * addr, size_t len, int advice)
PROT_EXEC Ausführen
PROT_READ Lesen
PROT_WRITE Schreiben
PROT_NONE Gar nicht
MAP_SHARED Sichtbar für andere Prozesse.
MAP_PRIVATE Schreibezugriffe verursachen private Kopie. (COW).
MCL_CURRENT Alle Seiten, die aktuell im Prozess eingeblendet sind.
MCL_FUTURE Alle Seiten, die zukünfitg in den Prozess eingeblendet werden.
MREMAP_MAYMOVE Die Adresse darf sich ändern.
MREMAP_FIXED Die neue Adresse wird zusätzlich übergeben.
POSIX_TYPED_MEM_ALLOCATE Mit Memory Mapping.
POSIX_TYPED_MEM_ALLOCATE_CONTIG Zusammenhängend
POSIX_TYPED_MEM_MAP_ALLOCATABLE Ohne Einfluss auf Allozierbarkeit
POSIX_MADV_NORMAL Default
POSIX_MADV_WILLNEED Speicher wird sofort verwendet.
POSIX_MADV_DONTNEED Speicher wird vorerst nicht verwendet.
POSIX_MADV_RANDOM Auf den Speicher wird chaotisch zugegriffen.
POSIX_MADV_SEQUENTIAL Speicher wird linear aufsteigend gefüllt.

Echtzeit-Erweiterungen.

struct posix_typed_mem_info
size_t posix_tmi_length
int madvise ( void * addr, size_t len, int advice)
int posix_madvise ( void * addr, size_t len, int advice)
int posix_mem_offset (const void * addr, size_t len, off_t * off,
size_t * contig_len, int * fd)
int posix_typed_mem_open (const char * name, int oflag, int tflag)
int posix_typed_mem_get_info (int fd, struct posix_typed_mem_info * info)
O_RDONLY Nur Lesen
O_WRONLY Nur Schreiben
O_RDWR Beides

Moderne Prozessoren unterstützen Memory Protection Keys, um Schreibzugriffe auf bestimmte Speicherbereiche zu unterbinden.

int pkey_alloc (unsigned long flags, unsigned long rights)
int pkey_mprotect (void * addr, size_t len, int prot, int pkey);
unsigned long pkey_get (int pkey);
int pkey_set (int pkey, unsigned long access_rights);
int pkey_free (int pkey);
Reserviert
PKEY_DISABLE_WRITE Nur Lesezugriff
PKEY_DISABLE_ACCESS Nur Execute-Rechte

Literatur