-         
Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 23

Thema: dynamische mehrdimensionale Arrays wie statische Arrays ansprechen?

  1. #1
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    4.840

    dynamische mehrdimensionale Arrays wie statische Arrays ansprechen?

    Anzeige

    hallo,
    wie kann man dynamische mehrdimensionale Arrays wie statische Arrays ansprechen?
    (C-code, aber streng genomen mit cpp kompiliert)

    z.B: ich habe einen statischen Array
    double arrayst[100][30]
    und brauche einen weiteren gleich großen dynamischen
    double arraydyn[100][30]

    memory allozieren könnte ich per
    double *mem = (double*) malloc(100*30*sizeof(double));

    aber wie kriege ich das jetzt sauber in einen 2-dim array?
    per union?

    Code:
    union a { 
      double *mem;
      double arraydyn[100][30];
    }
    
    
    a.mem=(double*) malloc(100*30*sizeof(double));
    
    for (int i=0; i<100; i++) {
      for (int j=0; j<30; j++)  {
       a.arraydyn[i][j]=arrayst[i][j]*0.123;
      }
    }
    wäre das so korrektes "C"?

    Oder geht es weniger umständlich mit C++ und new oder auch ganz anders?
    Geändert von HaWe (20.11.2019 um 12:01 Uhr) Grund: typo
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied Avatar von Rumgucker
    Registriert seit
    07.11.2019
    Ort
    Hamburg
    Beiträge
    108
    Moin Helmut,

    ich würde mehrdimensionale Arrays möglichst vermeiden, denn irgendwann weiß man nie so genau, was der Compiler da eigentlich indiziert. Lieber klare Verhältnisse schaffen:

    Code:
    #define X		100
    #define Y		30
    #define IND(x,y)	((x * X) + y)
    
    double arrayst[X * Y] = {47.11, 0.815};
    double *arraydyn = (double*)malloc(X*Y*sizeof(double));
    
    for (int i=0; i < X; i++) {
      for (int j=0; j < Y; j++)  {
       arraydyn[IND(i,j)]=arrayst[IND(i,j)]*0.123;
      }
    }
    Wenn das nicht Deinen Geschmack trifft, setz ich mich zum Rumspielen mal an den Compiler.

    Viele Grüße

    Wolfgang
    Geändert von Rumgucker (20.11.2019 um 08:57 Uhr)

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    4.840
    hallo,
    danke, aber gerade die dyn. mehrdim. Arrays sind unbedingt wichtig, damit der bestehende, für stat. arrays geschriebene Code 1:1 übenommen werden kann - ansonsten wäre es einfach.
    Ich bin allerdings nicht sicher, ob mein Code mit den unions wirklich 100% korrekt ist - oder ob es noch einfachere Wege gibt.

    (wichtig: es ist der von Arduino verwendete gpp C++14 Compiler!)
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied Avatar von Rumgucker
    Registriert seit
    07.11.2019
    Ort
    Hamburg
    Beiträge
    108
    Hallo Helmut,

    so wird Dein Code geschluckt

    Code:
    double arrayst[100][30];
    
    union {
      double *mem;
      double arraydyn[100][30];
    } a;
    
    
    a.mem=(double*) malloc(100*30*sizeof(double));
    
    for (int i=0; i<100; i++) {
      for (int j=0; j<30; j++)  {
       a.arraydyn[i][j]=arrayst[i][j]*0.123;
      }
    }
    Ich versuch ihn mal zu vereinfachen.

    Viele Grüße

    Wolfgang

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    4.840
    ich musste den Code jetzt testweise für den ESP8266 "downsizen", offenbar hat der bei weitem zu wenig RAM für heap.
    In meiner union-Def. war offenbar auch ein Fehler, ich habe deinen Code mal für mich angepasst:

    Code:
    #define LINE 20
    #define ROW  10
    
    void setup() {
      Serial.begin(115200);
      delay(1000);
      Serial.println();
      Serial.println("Serial() started");
    
      float arraystat[LINE][ROW ];
    
      union {
        float *mem;
        float arraydyn[LINE][ROW ]; // 10*20*4=800 bytes
      } a;
    
    
      a.mem = (float*) malloc(LINE * ROW  * sizeof(float));
    
      for (int i = 0; i < LINE; i++) {
        for (int j = 0; j < ROW ; j++) {
          arraystat[i][j]=i*(j*1000);
        }
      }
    
      for (int i = 0; i < LINE; i++) {
        for (int j = 0; j < ROW ; j++) {
          a.arraydyn[i][j] = arraystat[i][j] * 0.01;
        }
      }
    
      for (int i = 0; i < LINE; i++) { 
        yield();
        for (int j = 0; j < ROW ; j++) {
          Serial.println (a.arraydyn[i][j]);
        }
      }
    
    
    }
    
    void loop() {
    
    
    }
    - - - Aktualisiert - - -

    Sieht gut aus! (edit: zumindest auf den 1. Blick laut Serial.print)
    Jetzt wäre nur noch die Frage, ob's auch 2-dim ohne unions geht...
    Geändert von HaWe (20.11.2019 um 10:52 Uhr)
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied Avatar von Rumgucker
    Registriert seit
    07.11.2019
    Ort
    Hamburg
    Beiträge
    108
    Hallo Helmut,

    Zitat Zitat von HaWe Beitrag anzeigen
    Sieht gut aus!
    Ich bin noch nicht so ganz überzeugt. Ich denke, dass Dein Union auf einen sinnlosen 3000 double-Speicher zeigt, der dann einfach nie gebraucht wrid, weil er von dem malloc-Zeiger umgangen wird.

    Jetzt wäre nur noch die Frage, ob's auch 2-dim ohne unions geht...
    Daran grübele ich gerade.

    Viele Grüße

    Wolfgang

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    4.840
    Und mir ist auch noch nicht klar, ob die union a wirklich dynamisch im heap angelegt wird (und nicht im stack).
    eigentlich müsste es ja im Code per
    a->arraydyn[][] gehen, nicht per a.arraydyn[][]
    oder nicht?
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied Avatar von Rumgucker
    Registriert seit
    07.11.2019
    Ort
    Hamburg
    Beiträge
    108
    Hallo Helmut,

    "a->" ist "Pointer auf" und "a." ist "Member von".

    Ich bin überzeugt davon, dass die Lösung banal und naheliegend ist. Aber es gibt so Tage, an denen man wie vernagelt ist.

    Im Herzen finde ich meine IND-Makro-Lösung immer noch optimal

    #define IND(x,y) ((x * X) + y)

    und dann

    arraydyn[IND(i,j)] = arrayst[IND(i,j)]*0.123;

    Und sofort sind alle Probleme wie weggeblasen. Und es tut exakt das, was der Compiler auch tun würde. Denn wir quälen uns ja zur Zeit nur damit ab, dem Compiler genau diese Rechenregel auch für dynamische Arrays beizubrigen. Das ist unser ganzes Problem. Mehr nicht.

    Kannst Du Dich nicht vielleicht eventuell möglichweise - und natürlich: unter Protest - doch zu dieser zuerst gezeigten Lösung herablassen? Zumindest so lange, bis uns die Bretter vom Kopf fallen?

    Dann wird "IND(x,y)" einfach wieder durch "[x][y]" ersetzt und alles ist wieder gut.

    Viele Grüße

    Wolfgang

  9. #9
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    4.840
    es muss wie gesagt unbedingt ein dynamischer 2-dim array sein.

    (PS,
    und die Lösung soll später auch in analoger Weise für 3- oder 4-dim Arrays funktionieren)
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  10. #10
    Erfahrener Benutzer Fleißiges Mitglied Avatar von Rumgucker
    Registriert seit
    07.11.2019
    Ort
    Hamburg
    Beiträge
    108
    Hallo Helmut,

    wenn Du schreibst:

    pointer = malloc(LINE * ROW * sizeof(float));

    dann speicherst Du einen Pointer auf ein 1-dimensionales Array. Das will ich nicht ändern.

    Wenn Du den Compiler anweist, ein x-dimensionales Array anzulegen, dann speicherst du auch nur den Pointer auf ein 1-dimensionales Array. Die x-Dimensionalität entsteht allein dadurch, dass der Compiler beim Zugriff eine Rechenregel befolgt, die er aus der Definition des Arryas gewonnen hat

    Da es uns nicht gelingt, dem Compiler diese n-dimensionale Rechenregel auf für mit malloc erstellte 1-dimensionale Arrays zu übertragen, sollten wir dem Compiler das Rechnen einfach abnehmen.

    An Deinen gewünschten Dimensionen und mallocs usw. ändert das doch überhaupt nichts. Wir erklären lediglich den Compiler für doof und sagen ihm per Makro, wie er Arryay-Indizes zu berchnen hat.

    Das ermöglicht uns, alle Arrys uniform als double* anzusprechen, obwohl es natürlich unverändert mehrdimensionale Arrays sind. Double ist einfach der kleinste einzeln adressierbare Element aller Arrays.

    Von der Laufzeit, Speicherplatzbedarf oder so ändert sich gar nichts. Wir schließen lediglich vom Start weg Missverständnisse zwischen Compiler und uns aus.

    BTW: ich seh übrigens noch nen Fehler in meinem IND-Makro:

    #define IND(x,y) ((x * X) + y)

    Das große X muss natürlich durch ein großes Y ersetzt werden:

    #define IND(x,y) ((x * Y) + y)

    Himmel.

    Viele Grüße

    Wolfgang

Seite 1 von 3 123 LetzteLetzte

Ähnliche Themen

  1. cc5x und arrays
    Von amarok2 im Forum PIC Controller
    Antworten: 0
    Letzter Beitrag: 13.12.2010, 12:32
  2. mehrdimensionale arrays übergeben
    Von Roboman93 im Forum C - Programmierung (GCC u.a.)
    Antworten: 8
    Letzter Beitrag: 20.06.2008, 14:06
  3. Arrayzugriff / mehrdimensionale Arrays ?
    Von Skragan im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 06.06.2008, 14:16
  4. Arrays in Java
    Von hacker im Forum Software, Algorithmen und KI
    Antworten: 13
    Letzter Beitrag: 28.09.2006, 10:25
  5. BIT-Arrays bzw. Alternative
    Von tobimc im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 9
    Letzter Beitrag: 26.09.2004, 14:02

Berechtigungen

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