[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: [OT] Warum kein Speicherzugriffsfehler



Hallo,

Markus Schulz wrote:
Am Donnerstag, 14. Februar 2008 schrieb Martin Steigerwald:
Hallo!

Ich weiß, es ist off topic, aber ich bin jetzt grad so neugierig,
dass ich trotzdem mal fragen möchte. Ausgehend von der Diskussion zum
Speicherverbrauch von tab-basierten Konsolen bin ich bei einem
Galileobuch gelandet, wo auch ein Absatz zum virtuellen Speicher drin
ist und Speicher anfordern drin ist[1].

Da ist nettes Beispiel zum Speicher anfordern drin und auch ne
Erklärung, wie es zu einem Speicherzugriffsfehler kommen kann.

Nun wollte ich das mal ausprobieren:

martin@shambala> cat zugriffsfehler.c
#include <stdlib.h>
#include <stdio.h>

int main()
{
  char* puffer;                // Variable deklarieren
  puffer = malloc(4096);       // 4 KB = 4096 Bytes
                               // anfordern

  // Nun kann der Speicherbereich benutzt werden

  printf("4 KB Addressraum belegt ab: %ld\n", puffer);

  free(puffer);                // Speicherbereich
                               // wieder freigeben

  // Jeder Zugriff, der nach dem Freigeben auf den
  // Speicherbereich der Variable 'puffer'
  // erfolgt, führt zu einem Speicherzugriffsfehler

  printf("Zeiger auf den Speicher nach dem free(): %ld\n", puffer);

  printf("Und Speicherzugriffsfehler ;-)\n");

  int i;

  for (i==0; i<1; i++) {
          ^^
Das ist ein Vergleich und keine Initialisierung. D.h. i hat einen zufälligen Wert. Deshalb stürzt dein Programm ab, da i mit extrem hoher Wahrscheinlichkeit als Index auf eine nicht von deinem Programm allokierte Page zeigt.

da hast Du schon Recht, ist ein Vergleich und damit wird i nicht
initialisiert.

Ansonsten "funktionieren" die Programme beide erstmal, da der damit berechnete Zeiger (==virtuelle Adresse) noch auf eine gültige Adresse innerhalb deines Heaps zeigt.

Auch korrekt, beide funktionieren, solange der Speicher ausreicht.

Wenn du die Schleife länger laufen lässt "verlässt" du irgendwann den allozierten Heap Bereich deines Programmes, dann landest du in einer nicht allozierten Page und generierst damit ein Page Fault.

Und genau da liegt die Ursache für den Effekt, den Martin sieht.
Wenn das Programm mit der Schleife korrekt laufen würde, kommt es zu
einem Page Fault, wenn der Speicher nicht mehr ausreicht.

In der zweiten Version, ohne Schleife, reicht der verfügbare Speicher
anscheinend aus, um die Daten aufzunehmen. Man muss nicht immer explizit
Speicher allozieren, um mit Variablen arbeiten zu können (ich weiss,
schlechter Programmierstil und sollte verboten werden).

Gruss
Reinhold




Reply to: