Beispielcode Zeiger

Im Tutorium am 26. April wurde folgende übung gemacht, um Erfahrungen mit Zeigern zu erlangen.

Der Befehl malloc() versucht Speicher zu allozieren und wird in der Header-Datei stdlib.h definiert. Ist kein Speicher verfügbar, so wird der Wert 0 zurückgeliefert.
In C muss Speicher nach Benutzung wieder freigegeben werden. Dies geschieht mit dem Befehl free(), ebenfalls in stdlib.h definiert.


Kommentierter Sourcecode


#include "stdio.h" // Include für printf()
#include "stdlib.h" // Include für malloc() und free()

/***************************************************************
** Deklaration der einschiedenen Strukturen.
** struct ist ein Datentyp wie long.
** Man könnte nach der Definition (innerhalb der geschw. Klammern)
** also Variablen anlegen. Da hier keine globalen Variablen angelegt
** werden sollen folgt nach der geschlossenen geschw. Klammer ein Semikolon.
*/

struct Zeichen
{
char
Zeichen;
char Vordergrund;
char Hintergrund;
};

struct Zeile
{
struct
Zeichen * Spalten;
long UnnuetzeWeitereDaten;
};

struct Bildschirm
{
long
BildschirmID;
struct Zeile * Zeilen;
long AnzZeilen, AnzSpalten;
};

/***************************************************************
** Deklaration der Funktion FreeScreen.
** Die Funktion wird in NewScreen gebraucht, der Sourcecode
** folgt aber erst nach der Definition von NewScreen.
** Um Fehler zu vermeiden, wird dem Compiler bekannt gegeben, dass die
** später definiert wird (daher Semikolon hinter Funktionskopf)
*/

void FreeScreen(struct Bildschirm *);

/***************************************************************
** Eine BitMap für eine Textconsole anlegen.
** Entspricht Construktor für eine "class Bildschirm" in C++/Java
*/

struct Bildschirm * NewScreen(long vAnzZeilen, long vAnzSpalten)
{
struct Bildschirm * scr;
long y;

scr = malloc ( sizeof( struct Bildschirm ) );
if (scr) // Haben wir Speicher bekommen? (ist scr != 0?)
{
scr->AnzZeilen = vAnzZeilen; // In den allozierten Speicherblock schreiben
scr->AnzSpalten = vAnzSpalten;

/***************************************************************
** Alle Zeilen am Stück besorgen. (Speicher für ein Array von
** Zeilen.)
*/

scr->Zeilen = malloc ( scr->AnzZeilen * sizeof (struct Zeile) );
if( scr->Zeilen ) // Speicher bekommen? (ist scr->Zeilen != 0?)
{
y = scr->AnzZeilen;

/***************************************************************
** Für alle Zeilen wird ein Array entsprechend der Spalten
** angelegt. (Hier findet keine überprüfung statt, ob der Speicher
** verfügbar ist!! In echten Programmen aufpassen!)
*/

while ( y-- )
{
scr->Zeilen[y].Spalten = malloc ( scr->AnzSpalten * sizeof(struct Zeichen) );
}
}
else
{

/***************************************************************
** Wenn der Bildschirm angelegt werden konnte, aber kein
** Speicher für die Zeilen, dann war die Funktion nicht erfolgreich
** Alles Rückgängig machen und Fehler (0) zurückgeben.
*/

FreeScreen( scr );
scr = 0;
}

}
return( scr );
}

/***************************************************************
** Die Struktur "Bildschirm" wieder freigeben und alle unterge-
** ordneten Strukturen ebenfalls
** Entspricht Destruktor für eine "class Bildschirm" in C++/Java
*/

void FreeScreen(struct Bildschirm * scr)
{
long y = scr->AnzZeilen;

while(y--) free( scr->Zeilen[y].Spalten );
free( scr->Zeilen );
free( scr );
}

int main(void)
{
long a = sizeof(struct Zeichen);
struct Bildschirm * MeinBildschirm;

printf("Wieviel Speicher braucht eine struct Zeichen? => %d\n", a);
MeinBildschirm = NewScreen(25, 80);

FreeScreen(MeinBildschirm);
}