[OT] Warum kein Speicherzugriffsfehler
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++) {
puffer[i] = 0;
}
return 0; // Programm beenden
}
Gestartet ergibt dies wie gewünscht:
martin@shambala> gcc zugriffsfehler.c
martin@shambala> ./a.out
~/Computer/Programmieren/C/speicherverwaltung
4 KB Addressraum belegt ab: 134520840
Zeiger auf den Speicher nach dem free(): 134520840
Und Speicherzugriffsfehler ;-)
zsh: segmentation fault ./a.out
Zuerst probierte ich jedoch die naive Variante ohne for-Schleife:
martin@shambala> cat warum-kein-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 ;-) oder doch nicht?\n");
puffer[40]=1;
puffer[45]=232;
puffer[46]=232;
puffer[47]=232;
puffer[48]=232;
puffer[49]=232;
puffer[50]=232;
puffer[51]=232;
puffer[52]=232;
return 0; // Programm beenden
}
Und die sollte doch eigentlich auch gehen! Doch hier bleibt der gewünschte
Effekt aus:
martin@shambala> gcc -O0 warum-kein-zugriffsfehler.c
martin@shambala> ./a.out
~/Computer/Programmieren/C/speicherverwaltung
4 KB Addressraum belegt ab: 134520840
Zeiger auf den Speicher nach dem free(): 134520840
Und Speicherzugriffsfehler ;-) oder doch nicht?
Warum interessiert sich der Linux-Kernel nicht für die illegalen
Speicherzugriffe des zweiten Programms?
martin@shambala> cat /proc/version
Linux version 2.6.24.2-tp42-toi-3.0-rc5 (martin@shambala) (gcc version
4.2.3 20080114 (prerelease) (Debian 4.2.2-7)) #1 PREEMPT Wed Feb 13
00:18:13 CET 2008
[1] Virtueller Speicher:
http://www.galileocomputing.de/openbook/linux/linux_kap01_002.htm#mj02fce95f298e356b9ec54c17a8f92309
Ciao,
--
Martin 'Helios' Steigerwald - http://www.Lichtvoll.de
GPG: 03B0 0D6C 0040 0710 4AFA B82F 991B EAAC A599 84C7
Reply to: