Speicher für einen 2d-Vektor dynamisch reservieren

Beschreibung

Im Kapitel 4 des Skripts haben wir uns mit der dynamischen Reservierung von Speicher befasst. Das hier aufgeführte Beispiel soll zeigen, wie dynamischer Speicher für ein zweidimensionales Feld reserviert werden kann, so dass dieses wie ein normaler 2d-Vektor angesprochen werden kann. Die Vorbereitung erfolgt in folgenden Schritten:

  1. Zunächst wird Speicher für einen Zeigervektor reserviert.
  2. Danach wird Speicher für die eigentlichen Daten reserviert.
  3. Schließlich wird der Zeigervektor initialisiert.

Es wird erreicht, dass die Zeiger des Zeigervektors auf die passenden Stellen im Datenfeld zeigen. Jetzt können über den Zeigervektor die entsprechenden Stellen im Datenblock wie Zeilen angesprochen werden.

Das aufgeführte Beispiel ist als ein kleines Projekt mit drei Dateien erstellt. In der ersten Datei befindet sich der für das Thema relevante Quelltext. In den anderen beiden Dateien ist die sichere Abfrage einer ganzen Zahl ausgelagert.

Das Hauptprogramm in der Datei 2dVektorDynamisch.c

/*
Dateiname: 2dVektorDynamisch.c
Autor: Robert Heß & E2a
Version: 1.0
Datum: 25.10.2009
Beschreibung: 2d-Vektor dynamisch reservieren
*/

#include "getInt.h"
#include <stdlib.h>
#include <stdio.h>

int main()
{
    int width, height;      /* Breite und Höhe des Feldes */
    double **field=NULL;    /* Zeiger zum Ansprechen der Daten */
    int error=0;            /* Fehlerindikator */
    int i;                  /* lokale Laufvariable */

    /* Größe des Feldes vom Benutzer abfragen */
    width = getInt("Breite des Feldes", 5, 1000);
    height = getInt("H\224he des Feldes", 5, 1000);

    /* Speicher für den Zeigervektor reservieren */
    if(!error) {
        field = (double**)malloc(height*sizeof(double*));
        if(field==NULL) {
            printf("Konnte keinen Speicher reservieren!\n");
            error = -1;
        }
    }

    /* Speicher für Datenblock reservieren */
    if(!error) {
        field[0] = (double*)malloc(width*height*sizeof(double));
        if(field[0]==NULL) {
            printf("Konnte keinen Speicher reservieren!\n");
            error = -1;
        }
    }

    /* Zeigervektor initialisieren */
    if(!error) {
        for(i=1; i<height; i++)
            field[i] = field[i-1]+width;
    }

    /* Speicher verwenden */
    if(!error) {
        field[2][3] = 1.234;
        printf("field[2][3]: %g\n", field[2][3]);
    }

    /* Speicher freigeben */
    if(field) {
        if(field[0]) free(field[0]);
        free(field);
    }

    return 0;
}

Headerdatei getInt.h für die sichere Abfrage einer ganzen Zahl

/*
Dateiname: getInt.h
Autor: Robert Heß & E2a
Version: 1.0
Datum: 25.10.2009
Beschreibung: Eine ganze Zahl vom Benutzer absturzsicher abfragen.
*/

#ifndef GET_INT_INCLUDED
#define GET_INT_INCLUDED

int getInt(char text[], int min, int max);

#endif // #ifndef GET_INT_INCLUDED

Quellcodedatei getInt.c für die sichere Abfrage einer ganzen Zahl

/*
Dateiname: getInt.c
Autor: Robert Heß & E2a
Version: 1.0
Datum: 25.10.2009
Beschreibung: Eine ganze Zahl vom Benutzer absturzsicher abfragen.
*/

#include <stdio.h>

int getInt(char text[], int min, int max)
{
    int value=0;    // value to be entered by user
    char ch;        // character behind user input
    int finished=0; // flag for end of user input loop

    do {
        // print question
        printf("%s (%d-%d): ", text, min, max);

        // check for invalid number
        if(scanf("%d%c", &value, &ch)!=2)
            printf("Das war keine Zahl!\n");

        // check character behind user input
        else if(ch!=10&&ch!=13)
            printf("Ung\201ltiges Zeichen hinter der Zahl!\n");

        // check minimum limit
        else if(value<min)
            printf("Der Wert liegt unter dem Minimum!\n");

        // check maximum limit
        else if(value>max)
            printf("Der Wert liegt \201ber dem Maximum!\n");

        // user input correct
        else finished = 1;

        // flush input stream from key board
        fflush(stdin);

    } while(!finished);

    return value;
}
Seite 17