[gelöst] Rückgabe eines mehrdimensionalen dynamischen Arrays



  • Vorhaben:
    Innerhalb einer Funktion dynamische Arrays erzeugen und main() zurückgeben.

    Problem:
    Das Programm compiliert ohne Fehlermeldung. Beim Ausführen des Programms hängt sich dieses beim ausführen der printf-Zeile auf. Ich vermute mal, dass ich beim Übergeben des Zeigers irgendwelche Fehler gemacht habe. Zuvor hatte ich den dynamischen Array in main() erstellt. Dort habe ich keine Probleme gehabt ihn anschließend wieder zu benutzen.

    Beim Debuggen treten folgende Meldungen auf:
    `

    baggerleistung.exe!main() Zeile 26 + 0x3 Bytes C++

    baggerleistung.exe!__tmainCRTStartup()  Zeile 586 + 0x19 Bytes	C
    
    baggerleistung.exe!mainCRTStartup()  Zeile 403	C
    
    kernel32.dll!77b34911() 	
    
    [Unten angegebene Rahmen sind möglicherweise nicht korrekt und/oder
    
        fehlen, keine Symbole geladen für kernel32.dll]	
    
    ntdll.dll!77c0e4b6() 	
    
    ntdll.dll!77c0e489()
    
        matrix	0x00000000	int * *
    
        CXX0030: Fehler: Ausdruck kann nicht ausgewertet werden	
    

    `

    #include <cstdio>
    #include <cstdlib>
    
    void FeldFunktion(int **arr)
    {
    	int zeilen=3, spalten=5, i=0, z, s;
    	arr=(int**)malloc(zeilen*sizeof(int*));
    	for(i=0;i<zeilen;i++)
    		arr[i] = (int*)malloc( spalten*sizeof(int));
    	i=0;
        for(z=0; z<zeilen; z++)
            for (s=0; s<spalten; s++)
                 arr[z][s] = i++;
        for (z=0; z<zeilen; z++)
        {
            for (s = 0; s < spalten; s++)
                printf ("%3d", arr[z][s]);  
            puts("");
        }
    }
    
    int main()
    {
    	int** matrix=NULL;
    	FeldFunktion(matrix);
    	printf("%d",matrix[0][0]); //Programm hängt sich an dieser Stelle auf
    	return 0;
    }
    


  • void FeldFunktion(int **arr)
    

    Die Variable arr ist nur lokal in FeldFunktion bekannt.
    Lösung:
    entweder void FeldFunktion(int *arr)
    oder int
    FeldFunktion(/*sinnvoller weise zeilen- und spaltenanzahl übergeben*/)



  • malloc0r schrieb:

    Lösung:
    entweder void FeldFunktion(int ***arr)

    Den Lösungsansatz habe ich Probiert und den Code folgendermaßen abgeändert:

    #include <cstdio>
    #include <cstdlib>
    
    void FeldFunktion(int ***arr)
    {
    	int zeilen=3, spalten=5, i=0, z=0, s=0;
    	arr=(int***)malloc(zeilen*sizeof(int**));
    	for(i=0;i<zeilen;i++)
    		arr[i] = (int**)malloc( spalten*sizeof(int*));
    	i=0;
        for(z=0; z<zeilen; z++)
            for (s=0; s<spalten; s++)
    			*arr[z][s] = i++;
        for (z=0; z<zeilen; z++)
        {
            for (s = 0; s < spalten; s++)
                printf ("%3d", *arr[z][s]);  
            puts("");
        }
    }
    
    int main()
    {
    	int*** matrix=NULL;
    	FeldFunktion(matrix);
    	printf("%d",&matrix[0][0]); 
            // warning C4313: "printf": "%d" in der Formatzeichenfolge steht mit dem
            // Argument "1" vom Typ "int **__w64 " in Konflikt.
    	return 0;
    }
    

    Jetzt bekomme ich zum Einen eine Warnung für printf() in main() und einen Laufzeitfehler in FeldFunktion() mut folgenden Fehlermeldungen:

    `

    baggerleistung.exe!FeldFunktion(int * * * arr=0x00373f20) Zeile 13 +

        0x12 Bytes	C++
    
        -		*arr	0x00373f68	int * *
    
        +			0xcdcdcdcd	int *
    
        -		*arr[z]	0xcdcdcdcd	int *
    
    		CXX0030: Fehler: Ausdruck kann nicht ausgewertet werden	
    
    baggerleistung.exe!main()  Zeile 25 + 0x9 Bytes	C++
    
        -		matrix	0x00000000	int * * *
    
    		CXX0030: Fehler: Ausdruck kann nicht ausgewertet werden	
    
    baggerleistung.exe!__tmainCRTStartup()  Zeile 597 + 0x19 Bytes	C
    
    baggerleistung.exe!mainCRTStartup()  Zeile 414	C
    
    kernel32.dll!77694911() 	
    
    [Unten angegebene Rahmen sind möglicherweise nicht korrekt und/oder 
    
        fehlen, keine Symbole geladen für kernel32.dll]	
    
    ntdll.dll!77a9e4b6() 	
    
    ntdll.dll!77a9e489()
    

    `

    malloc0r schrieb:

    oder int** FeldFunktion(/*sinnvoller weise zeilen- und spaltenanzahl übergeben*/)

    Diesen Ansatz kommt, wenn ich ihn richtig verstanden habe, nicht in Frage, weil sich die Größe des Arrays im richtigen Programm erst in FeldFunktion() ergibt.



  • Die erste Möglichkeit geht so:

    void FeldFunktion (int*** m) 
    { 
    	int** a = *m = NULL;
    	// Matrix a 'wie gewohnt' allokieren.
    	// ...
    	// Wenn Allokierung gefunzt hat, Zeiger kopieren.
    	*m = a;
    }
    
    int main()
    {
    
        int** matrix;
        FeldFunktion(&matrix);
    ...
    

    bjosch schrieb:

    Diesen Ansatz kommt, wenn ich ihn richtig verstanden habe, nicht in Frage, weil sich die Größe des Arrays im richtigen Programm erst in FeldFunktion() ergibt.

    Das ist bloß eine Frage der Arbeitsteilung bzw. Aufteilung in Funktionen. IMO ist es die bessere Variante:

    int** MatrixErzeugen ( int zeilen, int spalten )
    { 
    	int** a = 0;
    	// Matrix a allokieren.
    	// ...
    	return a;
    }
    
    int MatrixDimensionieren ( int* zeilen, int* spalten )
    {
    	*zeilen = *spalten = 0;
    	// zeilen, spalten berechnen
    	// ...
    	return 0;
    }
    
    int main()
    {
    	int zeilen, spalten;
    	int** matrix;
    	if (MatrixDimensionieren(&zeilen, &spalten))
    		return 1;
    	matrix = MatrixErzeugen(zeilen, spalten);
    
    	return 0;
    }
    


  • Vielen Dank, so hat es funktioniert.

    Hier ist nochmal der vollständige Code, für alle die das gleiche Problem haben:

    #include <cstdio>
    #include <cstdlib>
    
    void FeldFunktion (int*** rm, int* rz, int* rs)
    {
    	int i,z,s;
    	int zeilen=3;
    	int spalten=5;
    	int** matrix = *rm = NULL;
    
    	matrix=(int**)malloc(zeilen*sizeof(int*));
    	for(i=0;i<zeilen;i++)
    		matrix[i] = (int*)malloc(spalten*sizeof(int));
    
    	i=0;
        for(z=0; z<zeilen; z++)
            for (s=0; s<spalten; s++)
    			matrix[z][s] = i++;
    
        *rm=matrix;
    	*rz=zeilen;
    	*rs=spalten;
    }
    
    int main()
    {
    	int s,z, zeilen, spalten;
    	int** matrix;
        FeldFunktion(&matrix, &zeilen, &spalten);
    	for (z=0; z<zeilen; z++)
        {
            for (s=0; s<spalten; s++)
                printf ("%3d", matrix[z][s]);  
            puts("");
        }
    }
    


  • fehlt noch die fehlerbehandlung, falls malloc fehlschlägt. außerdem castet man in c nicht den rückgabewert von malloc.


Anmelden zum Antworten