3d array in 1d array verpackt, arrayelemente vertauscht



  • Servus ich habe ein kleines Problem.

    Ich habe ein 3d-array mit einem allokierten 1d-pointer erzeugt. Das 3d-Array-Äquivalent ist a[M][N][O]. Der entsprechende 1d-pointer ist
    a[o + O*n + O*N*m], wobei die Kleinbuchstaben die jeweiligen Laufvariablen der Arraygrößen sind.

    Ich habe so ein array innerhalb einer Funktion erzeugt und zurückgegeben. Alles ist ganz normal und funktioniert, bis auf bei einer Funktion. Sobald dieses Array in eine neue Funktion übergeben wird, wird die Anordnung der Array-elemente total zerstört, allerdings ist der Vorgang in jedem Durchlauf der selbe, sprich die Anordnung der Arrayelemente immer gleich falsch.

    Hat jemand schon einmal ein ähnliches Problem gehabt?

    Mit freundlichen Grüßen,

    Inge



  • im simpelsten fall nur m,n,o vertauscht?
    poste mal code 🙂



  • Ingeborg schrieb:

    Servus ich habe ein kleines Problem.

    Ich habe ein 3d-array mit einem allokierten 1d-pointer erzeugt. Das 3d-Array-Äquivalent ist a[M][N][O]. Der entsprechende 1d-pointer ist
    a[o + O*n + O*N*m], wobei die Kleinbuchstaben die jeweiligen Laufvariablen der Arraygrößen sind.

    In C immer diese Reienfolge a[m*M*N + n*N + o] !
    Beispiel:

    #define M 4 
    #define N 5
    #define O 6
    
    typedef int(*ptr)[N][O]; 
    
    int main()
    {
    	void* void_ptr_d3 = malloc(M*N*O*sizeof(int));
    	ptr d3 = (ptr)void_ptr_d3;	 // Zeiger auf dreidimensionales Array
    	d3[1][2][3] = 4711;
    	int* d1 = (int*)void_ptr_d3; // Zeiger auf eindimensionales Array
    	d1[1*M*N+2*N+3] = d3[1][2][3];
    	int test = d1[1*M*N+2*N+3];
    	return 0;
    }
    

    mfg



  • Nee ich habe es. Es war eine falsche Deklaration. Ich hatte einer Funktion mit dem Eingabeparameter double complex* ein Array mit dem Typ double* übergeben. das hat die Struktur des arrays, warum auch immer verändert.

    Wie kann ich denn Eingabeparameter auf unbestimmen Typ hin verändern?
    Mir fällt da spontan void ein .

    *void fun1(int v1, void *v1)
    {}
    
    int main
    {
    int v2 = 4;
    double complex* v2 = {...};
    double *erg = NULL;
    erg = fun1(v1, v2);
    free(erg); free(v2);
    }
    

    Wäre das so denkbar?
    Mit dem void pointer habe ich noch nicht gearbeitet.

    Liebe Grüße,

    Inge

    @egon2

    Vielen Dank die Richtung stimmt. Wie man allerdings die Teile im 1d pointer anordnet, ist ja eigentlich bumms, man muss den Stil nur beibehalten. Bei Bibliotheken wie fftw, nfft3 wird sogar der Stil benötigt.

    Noch ne andere Frage egon2. Müssen die Pointer nicht wieder freigegeben werden? Irgendeiner hat mir mal gesagt, dass das der Grund ist warum Microsoft sooft patchen muss ;).



  • Ingeborg schrieb:

    Ich habe ein 3d-array mit einem allokierten 1d-pointer erzeugt. Das 3d-Array-Äquivalent ist a[M][N][O].
    Der entsprechende 1d-pointer ist
    a[o + O*n + O*N*m], wobei die Kleinbuchstaben die jeweiligen Laufvariablen der Arraygrößen sind.

    Die Indizes deiner Adressierung entsprechen auch meinen Überlegungen, wenn die Reihenfolge der Speicheranordnung des '3d' Arrays entsprechen soll.
    Man kann es sich auch mit einem kleinen Testprogramm verifizieren:

    #include <stdio.h>
    
    #define M 6
    #define N 5
    #define O 4
    
    #define INDEX_MAX (M*N*O-1)
    
    int get_value_at ( int* A, int m, int n, int o )
    {
    	return A[ O*N*m + O*n + o ];
    }
    
    int main()
    {
    	int A[M*N*O], 
    		B[M][N][O],
    		m, n, o, i = 0;
    
    	while ( i <= INDEX_MAX )
    		A[i] = i, i++;
    
    	i = 0;
    
    	for ( m = 0; m < M; m++ )
    		for ( n = 0; n < N; n++ )
    			for ( o = 0; o < O; o++ )
    				B[m][n][o] = i, i++;
    
    	// Testen der Reihenfolge auf Gleichheit.
    
    	for ( m = 0; m < M; m++ )
    		for ( n = 0; n < N; n++ )
    			for ( o = 0; o < O; o++ )
    				if ( B[m][n][o] != get_value_at(A, m, n, o))
    					goto FAULT;
    	goto OK;
    
    FAULT:
    	puts("FAULT!");
    OK:
    	puts("OK!");
    	return 0;
    }
    

    Ingeborg schrieb:

    Ich habe so ein array innerhalb einer Funktion erzeugt und zurückgegeben. Alles ist ganz normal und funktioniert, bis auf bei einer Funktion. Sobald dieses Array in eine neue Funktion übergeben wird, wird die Anordnung der Array-elemente total zerstört, allerdings ist der Vorgang in jedem Durchlauf der selbe, sprich die Anordnung der Arrayelemente immer gleich falsch.

    Wenn die Übergabe des Zeigers an eine Funktion dein Array zerstört, schreibst du vermutlich schon vorher irgendwo über Arraygrenzen hinaus, sodass der Stackaufbau dein Array killt. Die Übergabe des Zeigers allein darf die Elemente deines Arrays nicht verändern ( korrekter Code vorausgesetzt ).

    Gruß,
    B.B.



  • ...		
    		if ( B[m][n][o] != get_value_at(A, m, n, o))
    					goto FAULT;
    
    	puts("OK!");
    	return 0;
    FAULT:
    	puts("FAULT!");
    	return 0;
    

    🙄


Anmelden zum Antworten