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: