Pointer auf mehrdimensionales Array



  • Also das mit Arrays die keine festgelegt größe haben funktioniert! Ist ne "Erweiterung" von GCC.

    Was ich nun aber brauche ist nen Pointer auf ein solches Array.

    Ich will folgendes machen, ich weiß erst zur Laufzeit wieviele CPUs das System hat und ich bräuchte dann halt nen Array:

    struct foo_t *array[numCPU][2][4];
    

    Unter GCC kann ich folgendes machen:

    struct foo_t *array[][2][4];
    

    Solch ein Array kann man an das Ende einer Struktur packen. Ich bräuchte in meinem Fall aber 2 solcher Arrays und da das nicht geht (was mir auch klar ist), würde ich halt einfach 2 Pointer auf jeweils 1 Array folgenden Typs speichern:

    struct foo_t *array[][2][4];
    

    Ich hab nur kein Plan wie ich das hinbekomme oder besser gesagt, sind mir inzwischen die Ideen ausgegangen 😞



  • Mach das doch von anfang an vernünftig und verstrick dich nicht in irgendwelche compilerspezifischen Abhängigkeiten.
    Wenn du ein paar Infos mehr rausrückst, dann lässt sich bestimmt eine schnuckelige Lösung finden.

    Gruß,
    B.B.



  • Naja, wie gesagt ich will halt ein Array:

    struct foo_t *array[numCPU][2][4];
    

    bzw. 2 solcher Art. Ist für ne Art Slab-Allocator mit Magazinen. Ich speicher in dem Array Pointer auf die Struktur "foo".

    BigBrother schrieb:

    Mach das doch von anfang an vernünftig und verstrick dich nicht in irgendwelche compilerspezifischen Abhängigkeiten.

    Definiert vernünftig 😉 Außerdem bin ich schon sowas von Abhängig von GCC (da ich noch ein paar weitere spezifische Erweiterungen nutze) und finde gerade diese Sache nicht schlecht, bzw. ganz brauchbar.

    Aber wenn du weißt wie ich das ohne diese spezifische Erweiterung hinbekomme ohne mich dabei verrenken zu müssen, dann nur her mit dem Vorschlag!



  • typedef struct _cpu_t{
      int ax;
      int bx;
      int cx;
    }cpu_t;
    
    cpu_t cpus[];
    

    also was ich damit sagen wollte brings auf eine dimension und rechne dir wenn du es brauchst den rest selbst aus

    lg lolo



  • FlashBurn schrieb:

    struct foo_t *array[][2][4];

    Das ist aber kein Pointer auf ein Array, sondern ein dreidimensionales Array aus Pointern.

    Ein Pointer auf ein Array wäre

    struct foo_t (*array_ptr)[][2][4];
    

    Dem kannst du dann die Adresse von einem mit fester Größe deklarierten Array zuweisen, z.B.

    struct foo_t mein_array[42][2][4];
    array_ptr = &mein_array;
    

    Und zum Zugriff auf die Elemente musst du den Zeiger natürlich erst dereferenzieren, also

    (*array_ptr)[7][1][3].irgendwas = 23;
    


  • FlashBurn schrieb:

    Aber wenn du weißt wie ich das ohne diese spezifische Erweiterung hinbekomme ohne mich dabei verrenken zu müssen, dann nur her mit dem Vorschlag!

    Definiere verrenken 😃
    Ich weiß nicht, was deine Strukturen machen sollen, aaaber wie wärs hiermit:

    struct A
    {
    	char* s;
    	int i;
    };
    
        struct A a[2][2] = {0};
        struct A* p[4];
        p[0] = &a[0][0];
        p[1] = &a[0][1];
        p[2] = &a[1][0];
        p[3] = &a[1][1];
    


  • wieso die nicht einfach in das struct mit rein? zum glück gibts keine perfekte lösung, da bleibt platz für spekulationen 😃

    typedef struct _cpu_t{
      struct foo_t *data[2][4];
    }cpu_t;
    
    cpu_t cpus[];
    

    lg lolo



  • noobLolo schrieb:

    wieso die nicht einfach in das struct mit rein? zum glück gibts keine perfekte lösung, da bleibt platz für spekulationen 😃

    Jepp, in die Strutur reinpacken, das gefällt. Und für die totale Dynamisierung mit nem Doppelzeiger:

    typedef struct{ 
      struct foo_t** P2D; 
    }cpv; 
    
    int main() 
    { 
    	cpv* pcpv = malloc ( ...
    


  • namespace invader schrieb:

    Das ist aber kein Pointer auf ein Array, sondern ein dreidimensionales Array aus Pointern.

    Ich weiß, soll ja auch so sein und darauf brauch ich nen Pointer.

    BigBrother schrieb:

    Ich weiß nicht, was deine Strukturen machen sollen, aaaber wie wärs hiermit:

    Dein Bsp. funktioniert halt auch nicht, ich weiß erst zur Laufzeit wie groß das Array ist!

    Mit verrenken meine ich z.b. sowas:

    struct foo_t (*array)[2][4]= ADDR_CONST + cpu * sizeof(struct foo_t *[2][4]);
    
    (*array)[0][0]= bar;
    

    Obwohl das noch ne Möglichkeit ist die ich nutzen würde. Ich kann das natürlich auch alles per Hand machen, aber soll ja auch lesbar und nachvollziehbar bleiben.

    Also um es ganz genau zu erklären. Ich hab nen Array das ist 3-Dimensional, [dim1][dim2][dim3]. Mit dim1 wähle ich das 2-Dimensionale Array für die entsprechende CPU aus. Mit dim2 wähle ich dann eins von 2 vorhanden 1-Dimensionalen Arrays mit Pointern zu irgendwelchen Objekten aus.

    An anderer Stelle habe ich sowas auch schon gemacht, da definiere ich einfach:

    struct foo_t {
     ...
     struct bar_t *magazines[][2][4];
    };
    

    Dann kann ich ganz einfach darauf zugreifen:

    struct foo_t *ptr= parameter1;
    
    ptr->magazines[cpu][0][0]= foobar;
    


  • Achso, 3D, dann guck mal noobLolo`s Verpackungstechnik oder sowas wäre auch noch denkbar:

    int dim1 = 3, dim2 = 2, dim3 = 4;
    
    #define INDEX (x*dim2*dim1 + y*dim1+z)
    
    struct foo_t
    {
    	char* s;
    	int bar;	
    };
    
    void d3view ( struct foo_t* p, int x, int y, int z )
    {
    	printf ( "%s %d\n", p[INDEX].s, p[INDEX].bar );
    }
    
    int main() 
    { 
    
    	int x, y, z;
    	int n = 0;
    	struct foo_t* p = malloc ( dim1 * dim2 * dim3 * sizeof (*p));
    
    	for ( x = 0; x < dim1; x++ )
    		for ( y = 0; y < dim2; y++ )
    			for ( z = 0; z < dim3; z++ )
    				p[INDEX].s = "haellaeu woerld!",
    				p[INDEX].bar = n++;
    	for ( x = 0; x < dim1; x++ )
    		for ( y = 0; y < dim2; y++ )
    			for ( z = 0; z < dim3; z++ )
    				d3view (p, x, y, z);
    
    	return 0;
    }
    


  • @BigBrother

    Ich weiß das du mir nur helfen willst, aber lesbar und nachvollziehbar ist das nicht.

    Denn "#define"´s pack ich immer in die Header-Datei und wenn ich dann den Code debuggen muss, dann weiß ich doch gar nicht, was INDEX nun ist.

    Ich bringe jetzt einfach mal die Schleife die ich woanders schon nutze:

    struct foo_t *array[][2][MAGAZINE_SIZE], *bar;
    int x, cpu, ptrRead;
    
    cpu= getCpuNum();
    
    for(x= 0; x < 2; x++) {
     if((ptrRead= array[cpu][x][0])) {
      bar= array[cpu][x][ptrRead--];
      array[cpu][x][0]= ptrRead;
      return bar;
     }
    }
    
    //hier wird jetzt ne Funktion aufgerufen, die das Array wieder mit Pointer füllt
    

    So ungefähr sieht das aus und da noch nicht alles so klappt wie geplant, muss ich halt oft noch Ausgaben á la "printf("ptrRead: %d, bar: %08X\n",ptrRead,array[cpu][x][ptrRead]);" dazwischen schieben.

    Ich überlege schon die ganze Zeit, einfach die Daten so zu trennen das ich 2 Strukturen habe foo1_t und foo2_t und da dann jeweils am Ende dieses Array ohne die Grenzenangabe drin steht. Dann muss ich mir nicht den Kopf zerbrechen wie ich das hinbekommen, sondern muss nur nen ganzen Tag investieren und den Code verändern 😉



  • FlashBurn schrieb:

    Dann muss ich mir nicht den Kopf zerbrechen wie ich das hinbekommen, sondern muss nur nen ganzen Tag investieren und den Code verändern 😉

    gelegentlich kann sowas aber ganz nützlich sein, kommt schon mal vor das man sich einfach das mit den strukturen nicht genau überlegt hat, dann lieber das umbauen statt immer weiter drauf. das machts nicht besser...

    in der theorie denkt man immer ach das mach ich dann später wieder weg oder sauber, bzw. ist nur zum debuggen oder sonst was. afaik bleibt das dann aber bis zum ende, bzw. solange bis das einer neu || überarbeitet.

    also sollten sich anzeichen einer fehl strukturierung ergeben lieber sofort handeln.

    lg lolo



  • noobLolo schrieb:

    gelegentlich kann sowas aber ganz nützlich sein, kommt schon mal vor das man sich einfach das mit den strukturen nicht genau überlegt hat, dann lieber das umbauen statt immer weiter drauf. das machts nicht besser...

    Naja, die Struktur ist nicht unbedingt falsch, aber wenn ich einmal beim Umbauen bin, kann ich gleich versuchen den neuen Code (der fast genauso wie der alte ist) gleich auch so zu strukturieren und hoffen das es dann läuft.

    Werd also weiterhin mit den GCC spezifischen Sachen arbeiten und einfach meine Strukturen ein wenig anders machen.

    Hat dann nur den "Nachteil", das ein Speicherzugriff mehr dazu kommt (da ich die Adresse für die Struktur dann nicht mehr feststeht, sondern woanders gespeichert werden muss. Aber selbst das könnte ich mit ein wenig VirtualMemory Verschwendung wieder hinbekommen 😉



  • FlashBurn schrieb:

    @BigBrother

    Ich weiß das du mir nur helfen willst, aber lesbar und nachvollziehbar ist das nicht.

    Nicht nachvollziehbar, naja, mag sein dass, das Macro ein wenig aus der Luft gegriffen scheint, das ist lediglich die Berechnungsvorschrift für den Index des Strukturarrays.

    FlashBurn schrieb:

    Denn "#define"´s pack ich immer in die Header-Datei und wenn ich dann den Code debuggen muss, dann weiß ich doch gar nicht, was INDEX nun ist.

    Das Macro kann man natürlich weglassen, indem man z.B. unsigned i;
    .. i = x*dim2*dim1 + y*dim1+z .. schreibt.



  • BigBrother schrieb:

    Das Macro kann man natürlich weglassen, indem man z.B. unsigned i;
    .. i = x*dim2*dim1 + y*dim1+z .. schreibt.

    Genau da liegt ja das Problem. Ich musste auch 2mal lesen und per "Hand" nachrechnen ob das stimmt was du geschrieben hattest (aber ist richtig 😉 ).

    Aus dem Macro geht halt nicht hervor (bzw. wenn du einfach nur INDEX dastehen hast), dass das Array 3-Dimensional ist und welche Dimension was ist. Es muss einen förmlich anspringen was man da will 😉

    Wie gesagt auch der Programmierer ist faul und will so wenig wie nötig denken (ansonsten hätten wir nicht die ganzen Hochsprachen die uns schon vieles abnehmen).

    Es ist dem Sinne zwar auch "Geschmackssache", aber das ist OO auch 😉


Anmelden zum Antworten