Teil eines mehrdimensionalen Arrays an Funktion übergeben



  • Hallo,

    ich möchte einen Teil eines mehrdimensionalen Arrays an eine Funktion übergeben, die gleichzeitig auch mit statischen Arrays arbeiten soll.
    Funktionen, die mit jeweils einer der beiden Aufgabenstellungen klar kommen habe ich, ich bekomme nur beides nicht kombiniert - ich verstehe noch nicht einmal, warum das für den Compiler einen Unterschied macht 😞

    Was ich habe:

    void f(int **pix){
    	std::cout<<pix[2][3]<<std::endl;
    }
    
    void g(int pix[5][5]){
    	std::cout<<pix[2][3]<<std::endl;
    }
    
    int main(){
    	int ***p_pix;
    	int pix[5][5];
    
    	p_pix=new int**[5];	
    	p_pix[1]=new int*[5];	
    	p_pix[1][2]=new int[5];
    
    	p_pix[1][2][3]=23;
    	pix[2][3]=45;
    
    	f( p_pix[1]);
    //	f(  pix  );     ergibt Fehlermeldung 1
    
    	g(  pix  );
    //	g( p_pix[1]);   ergibt Fehlermeldung 2
    
    	delete[] p_pix[1][2];
    	delete[] p_pix[1];
    	delete[] p_pix;
    	return 0;
    }
    
    Fehlermeldung 1:
    test_dynarray_an_fkt.cpp: In function ‘int main()’:
    test_dynarray_an_fkt.cpp:23: error: cannot convert ‘int (*)[5]’ to ‘int**’ for argument ‘1’ to ‘void f(int**)’
    
    Fehlermeldung 2:
    test_dynarray_an_fkt.cpp: In function ‘int main()’:
    test_dynarray_an_fkt.cpp:26: error: cannot convert ‘int**’ to ‘int (*)[5]’ for argument ‘1’ to ‘void g(int (*)[5])’
    

    Ideen für Workarounds habe ich auch (die Verwendung der beiden Funktionen, der Verzicht auf statische Arrays zugunsten von nur dynamischen Arrays, ...).
    Ich frage hier nur, weil ich gerne verstehen würde, warum der Compiler nicht von 'int**' zu 'int (*)[5]' konvertieren kann.

    Vielen Dank schon mal


  • Mod

    dynArray schrieb:

    Ich frage hier nur, weil ich gerne verstehen würde, warum der Compiler nicht von 'int**' zu 'int (*)[5]' konvertieren kann.

    Das liegt daran, dass es sich hier um sehr verschiedene Dinge handelt.

    Auf der rechten Seite hast du ein klassisches int-Array. Alle Elemente sind hintereinander im Speicher abgelegt. Ob es jetzt ein-, zwei- oder mehrdimensional ist, ist völlig egal. Wichtig ist, das alles am Stück ist, so dass man Pointerarithmetik machen kann.

    Das auf der Linken sind Zeiger auf Zeiger auf int. Die konkreten int-Daten können überall im Speicher verteilt sein. Wenn du jetzt darauf Pointerarithmetik versuchen würdest (nichts anderes ist ja ein Arrayzugriff), dann geht das total schief. Deshalb lässt der Compiler das auch nicht zu.

    Verstanden oder soll ich mich im Bildchenmalen bemühen?

    einfache Abhilfe: Arbeite mit std::vector oder einer anderen Containerklasse.

    etwas schwierigere Abhilfe, deren genaue Syntax ich mir jetzt nicht überlegen will: p_pix muss halt auf richtige Arrays zeigen, nicht bloß auf weitere Zeiger.



  • theoretisch sollte auch das funktionieren (nicht getestet):

    template <typename ArrayTape>
    void f(const ArrayType& pix){
        std::cout << pix[2][3] << std::endl;
    }
    

    diese Variante sollte dann
    int**, int [...][...] und auch vector<vector<int> > zulassen...

    EDIT: ein Beispiel (getestet und funktioniert :D)

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    template <typename ArrayType>
    void print_array_val(const ArrayType& the_array, int x, int y)
    {
    	cout << the_array[x][y] << endl;
    }
    
    int main(int argc, char** argv)
    {
    	vector<vector<int> > data;
    	for (int n = 0; n < 10; ++n)
    	{
    		vector<int> inner_data;
    		for (int m = 0; m < 10; ++m)
    			inner_data.push_back(n * m);
    		data.push_back(inner_data);
    	}
    
    	print_array_val(data, 5, 5);
    
    	int arr[5][5];
    	for (int n = 0; n < 25; ++n)
    		arr[n / 5][n % 5] = n;
    
    	print_array_val(arr, 3, 2);
    
    	int** dynarray = new int* [5];
    	for (int n = 0; n < 5; ++n)
    	{
    		dynarray[n] = new int[5];
    		for (int m = 0; m < 5; ++m)
    			dynarray[n][m] = n + m;
    	}
    
    	print_array_val(dynarray, 2, 3);
    
    	for (int n = 0; n < 5; ++n)
    		delete[] dynarray[n];
    	delete[] dynarray;
    
    	cin.get();
    
    	return 0;
    }
    


  • Hier hatte ich schonmal viel erklärt und sogar ein Bildchen gemalt.


Anmelden zum Antworten