Anzeige:
Ergebnis 1 bis 7 von 7

Thema: Erstellen einer Matrix führt zu Problemen

  1. #1
    Registrierter Benutzer Avatar von Berufspenner
    Registriert seit
    30.03.2002
    Ort
    Hamburg
    Beiträge
    567

    Erstellen einer Matrix führt zu Problemen

    Moin moin,

    heute bin ich mal in eigener Sache aktiv und gleich zu beginn frag ich mich, ob der Threadtitel sehr aussagekräftig ist naja, was solls

    Also, ich schreib gerade an einem Programm, mit dem ich dynamisch mit Hilfe von calloc() Speicher für eine Matrix freigeben möchte, um mit ihr später ein paar Berechnungen durchzuführen. Mein bissheriger Code ist folgender:

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    
    double** creat_matrix(int);
    
    int main()
    {
        int dim, i, j;
        double **matrix;
        double b;
    
        printf("Bitte Dimension der Matrix eingeben (1,2 oder 3 Dimensionen)!\n");
        scanf("%d", &dim);
    
        if(dim < 1 || dim > 3)
        {
            printf("Die gew%chlte Dimension ist ung%cltig\n",132,129);
            return 1;
        }
    
        creat_matrix(dim);
    
        for(i = 0; i < dim; i++)
        {
            for(j = 0; j < dim; j++)
            {
                printf("Bitte Bitte Element [%d][%d] eingeben!\n",i,j);
                scanf("%f", &b);
                matrix[i][j] = b;
            }
        }
    
    
    
    
        free(matrix);
    
        return 0;
    }
    
    
    double** creat_matrix(int i)
    {
        int size, j;
        double **matrix;
    
        //Erstelt 1-dim. Feld (Zeilen) von double-Zeigern
        matrix = (double**) calloc(i, sizeof(double*));             
    
        //Überprüft, ob calloc()-Aufruf konrekt ablief
        if(matrix == NULL)                                          
        {
            printf("Speicher konnte nicht reserviert werden\n");
            
            //Sollte es zu Problemen gekommen sein, Speicher leeren
            free(matrix); 
            
            //Programm beenden                                          
            return 1;                                               
        }
    
        for(j = 0;j < i; j++)
        {
            //erstellt zur i-ten Zeile ein eindimensionales Feld der Länge i (Spalten)
            matrix[j] = (double*) calloc(i, sizeof(double));         
                                                                      
                                                                    
    
            //Ist die Speicherreservierung nicht erfolgreich, dann wird jedes zuvor erfolgreich reservierte Feld
            //wieder freigegeben
            if(matrix[j] == NULL)                                   
            {                                                       
                int x;                                              
                for(x = 0; x < j; x++)
                {
                    free(matrix[x]);
                }
                
                //gibt zum Schluss den "Zeilen-Zeiger" frei
                free(matrix);                                       
                printf("Speicher konnte nicht reserviert werden\n");
            }
        }
        return matrix;
    }
    Mir stellen sich nun zwei Probleme in den weg

    1. Wenn ich die Matrix mit
    Code:
    matrix = (double**) calloc(i, sizeof(double*));
    erstelle und danach mit
    Code:
    if(matrix == NULL)
    überprüfen will, ob das geklappt hat, dann pfeffert mir mein Compiler nen nassen Waschlappen um die Ohren. Verständlich, denn ich vergleiche int mit double und das geht ja wohl nur in die Hose. Und dann auch noch nen Zeiger. Nur wie bekomm ich die Abfrage sinnvoll übertragen? Das Feld soll eins vom Typ double werden. Weder ein naives
    Code:
    if(matrix == 0.0)
    noch ein noch das casten von "matrix" hilft da wirklich. Mir ist klar, dass ich dort einen Gedankenfehler mache, der mir grad aber nicht einfallen will.

    2. Wenn ich die Abfrage von 1. auskommentiere und es compiliere, dann läuft das auch, nur sobald ich die erste Matrixkomponente abfrage und eingeben will, stirbt mir mein Programm einfach weg. Irgendwo wird er sich da dann wohl im Speicher festfressen, ich versteh nur nicht direkt wo

    Ich hoffe, dass mich mal jemand an die Hand nehmen und mich durch das gewirr führen kann
    C und C++

  2. #2
    Registrierter Benutzer Avatar von ContainerDriver
    Registriert seit
    10.01.2003
    Beiträge
    418
    Hallo,

    zu 1.: du vergleichst nicht double mit NULL, sondern einen Pointer auf einen Pointer mit NULL. Bist du sicher, dass der Compiler in der Zeile aussteigt (Fehlermeldung)?
    Außerdem würde das Programm in der Funktion nicht mit dem return 1 beendet, meinst du vielleicht exit(1)?

    zu 2.: du holst dir zwar den Speicher für matrix, verwendest ihn aber nicht in deiner main-Funktion! Es müsste heißen:
    Code:
    matrix=creat_matrix(dim);
    . Das free() am Ende der main-Funktion gibt dann übrigens nicht den ganzen Speicher frei.

    Gruß, Florian
    Ein gebrechlich Wesen ist der X-Server.

  3. #3
    Registrierter Benutzer Avatar von Berufspenner
    Registriert seit
    30.03.2002
    Ort
    Hamburg
    Beiträge
    567
    Zitat Zitat von ContainerDriver Beitrag anzeigen
    zu 2.: du holst dir zwar den Speicher für matrix, verwendest ihn aber nicht in deiner main-Funktion! Es müsste heißen:
    Code:
    matrix=creat_matrix(dim);
    "Manchmal" hat man einfach Tomaten auf den Augen... Danke, jetzt schmiert er mir zumindest nicht mehr ab

    Zitat Zitat von ContainerDriver Beitrag anzeigen
    zu 1.: du vergleichst nicht double mit NULL, sondern einen Pointer auf einen Pointer mit NULL. Bist du sicher, dass der Compiler in der Zeile aussteigt (Fehlermeldung)?
    Außerdem würde das Programm in der Funktion nicht mit dem return 1 beendet, meinst du vielleicht exit(1)?
    Ok, war jetzt doof formuliert, dass er nen double mit nem int vergleich. So wie du das sagst wars schon gedacht, hat aber leider nicht den weg über die Tastatur in mein Posting geschaft Wenn ich genauer hinsehe, dann erkenn ich den Fehler auch endlich. exit(1) schafft da die passende Abhilfe, denn es macht keinen Sinn, einer Funktion von "Typ" double** einen Funktionswert vom Typ int zurückgeben zu lassen

    Zitat Zitat von ContainerDriver Beitrag anzeigen
    Das free() am Ende der main-Funktion gibt dann übrigens nicht den ganzen Speicher frei.
    Müsste ich dann eher eine Routine schreiben, die mir dann erstmal die "Spalten-Pointer" freigibt und dann den "Zeilen-Pointer" freigibt?

    Danke, das hat mir sehr geholfen, denn jetzt sollte es klappen. Wenn man zu nah vor einem Problem sitzt, dann hat man einfach nicht mehr den Überblick. Danke nochmal.

    Gruß
    Geändert von Berufspenner (27-05-2008 um 16:02 Uhr)
    C und C++

  4. #4
    Registrierter Benutzer Avatar von jeebee
    Registriert seit
    01.01.2005
    Ort
    Bern || Zürich
    Beiträge
    540
    Zitat Zitat von Berufspenner Beitrag anzeigen
    Müsste ich dann eher eine Routine schreiben, die mir dann erstmal die "Spalten-Pointer" freigibt und dann den "Zeilen-Pointer" freigibt?
    Genau. Alternativ kannst du auch das ganze einfach in einem 1-d Array ablegen und dann jeweils den Index berechnen.

    Code:
    double* creat_matrix(int dim)
    {
        double *m = calloc(dim*dim, sizeof(double));
        return m;
    }
    Dann kannst du z.B. mit einem Makro
    Code:
    #define ELEM(m, dim, i, j) (m[i*dim + j])
    das Matrix-Element (i,j) zurückgeben.

    Hier kannst du dann einfach mit free(m) die ganze Matrix freigeben.

    edit: was soll eigentlich dein 'dim' genau darstellen: die Anzahl Dimensionen der Matrix (1) oder die Grösse der 2-d quadratischen Matrix (2)? Nach dem Code in der main(9 wäre es (1), nach dem Code in creat_matrix() wäre es (2). Wenn du (1) machen willst, müsstest du zusätzlich noch eine Grösse der Matrix haben.
    Geändert von jeebee (28-05-2008 um 07:23 Uhr)
    my very own 128 bit integer
    C4 D3 B8 A8 9E A0 C6 EC 7D EC A8 15 28 D1 92 58
    more information

  5. #5
    Registrierter Benutzer Avatar von Berufspenner
    Registriert seit
    30.03.2002
    Ort
    Hamburg
    Beiträge
    567
    Ok, dann werd ich mir zum Freigeben des Speichers noch einmal eine Routine schreiben.

    Ne ne, die Variable soll schon den Wert der quadratischen Matrix angeben, also Fall (2). Wie du jetzt auf Fall (1) kommst ist mir grad nicht klar
    C und C++

  6. #6
    Registrierter Benutzer Avatar von Berufspenner
    Registriert seit
    30.03.2002
    Ort
    Hamburg
    Beiträge
    567
    So, ich hab jetzt nochmal eine kleine Routine zum freigeben des gesamten Speichers geschrieben
    Code:
    void free_matrix(double** array, int size)
    {
        int i;
    
        for(i = 0; i < size;i++)
        {
            free(array[i]);
        }
    
        free(array);
    }
    die ich dann mit
    Code:
    free_matrix(matrix,dim);
    aufrufe. Der Compiler haut mir keinerlei Beanstandungen um die Ohren oder sonst was und abschmieren tut das Programm auch nicht. Kann ich damit jetzt sicher sein, dass der gesamte Speicher wieder freigegeben wird?
    C und C++

  7. #7
    Registrierter Benutzer Avatar von ContainerDriver
    Registriert seit
    10.01.2003
    Beiträge
    418
    Ich denke schon; wenn du ganz sicher gehen willst, dann kannst du dir mal valgrind anschauen (bzw. einfach installieren und dann "valgrind ./programm" aufrufen), damit lassen sich Speicherlecks und allgemein Fehler im Umgang mit allozierten Speicher finden. Wenn du direkt die Stelle angezeigt haben willst, wo im Quellcode der Fehler auftrat musst du dein Programm mit dem Schalter "-g" übersetzen.

    Gruß, Florian
    Ein gebrechlich Wesen ist der X-Server.

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •