C Wieso muss der Zeiger global sein?

foggy80

Lt. Commander
Registriert
Juli 2008
Beiträge
1.034
Hallo,
Habe folgenden Quelltext geschrieben:
/* readdir */
# include <sys/types.h>
# include <dirent.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>

DIR *dir;

int main () {

char *ordner;

struct dirent *dirzeiger;

scanf ("%s", ordner);

if ((dir=opendir (ordner)) == NULL) {
fprintf (stderr, "Fehler bei opendir ...\n");
//return 1;
}

int b;
for (b = 1; (dirzeiger=readdir(dir)) != NULL; b++)
printf ("%d.%s\n", b, (*dirzeiger).d_name);

int a;
scanf ("%d", &a);

if (closedir (dir) == -1)
printf ("Fehler beim Schliessen von %s\n", ordner);
return 0;
}

wenn ich das DIR *dir; in die main-Klammer schiebe, also:
/* readdir */
# include <sys/types.h>
# include <dirent.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>

int main () {

DIR *dir;
...

stürzt das Programm ab. Wieso?
Ich hätte nie gedacht dass der Anfang eines Programmierers so träge sein könnte!

Danke für die Hilfe
foggy
 
Das hat wohl weniger was mit dem DIR-Zeiger als mit dem 'char* ordner' zu tun.

scanf erwartet bei dem Format-Token '%s' einen ausreichend großen Puffer, in den die Funktion schreiben kann.

Nun zeigt 'ordner' mal auf gar nichts, da diese Variable nicht initialisiert wurde (heißt: 'Datenmüll' [undefinierte/unbekannte Werte] wird als Adresswert interpretiert und zeigt sehr wahrscheinlich auf einen Bereich, der Deiner Anwendung nicht gehört und/oder nicht zum Schreiben markiert ist).
Zu erwartendes Verhalten: Zugriffsverletzung 0xC0000005 beim Schreiben auf Adresse <Adresse, auf die 'char* ordner' zeigt>

Das Verhalten Deines Programms ist im übrigen somit nicht einmal definiert, da aufgrund der fehlenden Initialisierung 'ordner' dort jedes Mal ein anderer Wert stehen kann und das Programm nicht mal zwingend abstürzen muss. Du änderst mit dem Verschieben der Variable 'DIR* dir' auch den Stack bzw. den Stackpointer, weshalb Du einmal genügend Speicher hast (Variable global), um in 'char* ordner' zu schreiben und einmal nicht (Variable lokal, in main).

Lösung: 'ordner' mit gültigem Wert initialisieren - Stichwort: Speicher implizit (char-Array, liegt auf dem Stack der Anwendung) oder explizit (Heap-Speicher mit malloc) anfordern.
 
Okay, ich hab ne weile gebraucht, aber verstehe jetzt wahrscheinlich was du meinst. Heißt das also soviel, dass wenn ich statt "char *ordner" dann einfach "char ordner[300]" schreibe, da ein Speicher von 300 Bytes reserviert wird und der *ordner-Zeiger dort dann hinzeigt?
 
Zurück
Oben