- Akku Tests und Balkonkraftwerk Speicher         
Ergebnis 1 bis 10 von 23

Thema: class mit übergebenen array Größen erstellen

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    HaWe
    Gast

    class mit übergebenen array Größen erstellen

    hi,
    ich möchte eine class tMenu erstellen, die per tMenu::init(a,b) zur Laufzeit einen array tMenu::array[a][b] erzeugen kann.

    In der Art:

    Code:
    class tMenu {
      
      protected:    
      
      public:      
        
        tMenu () : 
           {  }
    
           char CAPTLEN;
           char MENULEN;
        
           void init(char captlen,  char menulen) { 
             CAPTLEN = captlen;
             MENULEN = menulen;            
           }
    
           char list[MENULEN][CAPTLEN];
    };
    
    //
    klar geht das so nicht, wegen const für array-Dimensionen -
    aber wie kriegt man es dennoch hin?

    - - - Aktualisiert - - -

    ich bin jetzt 1 Schritt weiter, über assert -
    leider kann ich damit nur einen 1-dim array erstellen, keinen 2-dim.

    wie geht das denn nun wohl...?

    Code:
    #include <cassert>
     
    class tMenu {
      
      protected:         
            char * list;
            char MENULEN, CAPTLEN;      
      
      public:      
        
         tMenu (char menulen, char captlen) // constructor
         {
            assert(menulen > 0); 
            assert(captlen > 0); 
            list = new char[menulen]; 
        //  list = new char[menulen][captlen];   // alternat. >> error!
            MENULEN = menulen;
            CAPTLEN = captlen;
         }      
    
     
         ~tMenu() // destructor
         {
           // Dynamically delete the array we allocated earlier
           delete[] list ;
         }
    
    };
    Geändert von HaWe (04.12.2018 um 07:57 Uhr)

  2. #2
    shedepe
    Gast
    Du bist schon ganz gut in der richtigen Richtung unterwegs.

    Ein multidimensional array in C++ ist eigentlich eine Liste von Pointer. D.h. list[0] z.B. liefert einen Pointer zurück, und auf diesem wird mit list[0][1] z.B. auf das 2. Element des Pointer zugegriffen.
    Deshalb kann man wie in Variante 1 das mit einer Schleife initialisieren.

    Variante 1
    Code:
    char * list;
    list = new char[menulen * captlen]
    Alternativ kann man auch einen außreichend großen Block Speicher allokieren.

    Variante 2
    Code:
    char ** list;
    list = new char*[menulen];
    for(int i = 0; i < captlen; i++)
    {
       list[i] = new char[captlen];
    }
    //Zugriff auf stelle x, y
    char val = list[x * captlen + y)
    Nachzulesen gibt es das z.B. hier: https://stackoverflow.com/questions/...in-c-using-new

    Ein Tipp außerdem: Solltest du das auf einem Mikrocontroller machen wollen solltest du auf new verzichten. Am PC würde ich auch auf die Arrays verzichten und stattdessen einen std::vector<std::vector<char>> list verwenden. Dann muss man nämlich den Speicher nicht von Hand aufräumen und hat dynamische Größen geschenkt bekommen.

  3. #3
    HaWe
    Gast
    Zitat Zitat von shedepe Beitrag anzeigen
    Du bist schon ganz gut in der richtigen Richtung unterwegs.

    Ein multidimensional array in C++ ist eigentlich eine Liste von Pointer. D.h. list[0] z.B. liefert einen Pointer zurück, und auf diesem wird mit list[0][1] z.B. auf das 2. Element des Pointer zugegriffen.
    Deshalb kann man wie in Variante 1 das mit einer Schleife initialisieren.

    Variante 1
    Code:
    char * list;
    list = new char[menulen * captlen]
    Alternativ kann man auch einen außreichend großen Block Speicher allokieren.

    Variante 2
    Code:
    char ** list;
    list = new char*[menulen];
    for(int i = 0; i < captlen; i++)
    {
       list[i] = new char[captlen];
    }
    //Zugriff auf stelle x, y
    char val = list[x * captlen + y)
    Nachzulesen gibt es das z.B. hier: https://stackoverflow.com/questions/...in-c-using-new

    Ein Tipp außerdem: Solltest du das auf einem Mikrocontroller machen wollen solltest du auf new verzichten. Am PC würde ich auch auf die Arrays verzichten und stattdessen einen std::vector<std::vector<char>> list verwenden. Dann muss man nämlich den Speicher nicht von Hand aufräumen und hat dynamische Größen geschenkt bekommen.
    danke,
    ich wollte es tatsächlich auf einem ESP oder ARM machen, evtl. aber auch kompatibel zu einem Raspi.
    (schön ntl, wenn es später auch auf AVRs läuft.)
    vector kenne ich noch nicht, aber für später ist es wichtig, dass ich prinzipiell auf diese Weise den Zugriff habe auf 2-dim arrays, sowohl intern als auch dann von der aufrufenden Funktion:

    this->char list[10][20]={"line0", "line1", "line2", "line3",..., "line9"};
    Serial.println(this->list[k]);

    tMenu mymenu(10,20);
    strcpy(mymenu.list[5], "5 new testline", sizeof(testline));
    mymenu.list[5][0]='>';

    also Zugriff direkt auf die 2-dim Struktur, ohne immer rechnen zu müssen
    x * captlen + y

    Wie macht man es also am besten, cross-over-Plattform-kompatibel?
    Geändert von HaWe (04.12.2018 um 09:46 Uhr)

  4. #4
    shedepe
    Gast
    Für den ESP32 kann ich leider nichts sagen.
    Deshalb erläutere ich kurz die Überlegung dahinter warum man auf einem Mikrocontroller in der Regel keinen Speicher dynamisch allokieren möchte.
    Das Problem dabei ist: Wenn man Speicher mit malloc oder new allokiert, wird dieser intern von der libc verwaltet. Diese schaut prinzipiell wo ist noch Speicher übrig bzw. wo ist genügend speicher am Stück übrig. Wenn man jetzt aber z.B. auf einem Atmega sehr wenig Speicher hat, wird dieser sehr schnell durchlöchtert wenn man häufiger Speicher reserviert bzw. wieder frei gibt. Die libc implementiert zwar Algorithmen um diesen Speicher möglichst intelligent zu verwalten, das funktioniert nur mit sowenig Speicher nicht so super bzw. kann sehr viel Performance klauen. Zudem kann man nicht zur compilezeit sagen ob der Speicher überhaupt reicht.

    Bei größeren Controllern wie dem ESP32 kann es durchaus möglich sein, dass effizient mit dynamisch allokiertem Speicher umgegangen werden kann.

    Ob es Sinn macht die Container aus der C++ Standardlib zu verwenden auf dem ESP32, müsstest du auch noch mal recherieren. Diese machen einem das Leben wesentlich leichter, kosten aber natürlich auch etwas mehr Speicher und CPU Leistung.

  5. #5
    HaWe
    Gast
    neinnein, ich habe "nur" einen esp8266, alternativ M0, M3, M4, aber es wäre ntl schön auch auf dem Raspi und auch AVR Mega oder gar Nano: grundsätzlich eben Plattform-unabhängig.
    Das mit den Löchern verstehe ich, aber es wird vorraussichtlich nicht so häufig passieren mit dem destructor, viel häufiger werden constructors nacheinander aufgerufen werden.

    Was würdest du also vorschlagen für die Erzeugung von 2-dim arrays
    - wichtig, wie gesagt, ist der direkte Zugriff auf alle einzelnen Speicherzellen beider Dimensionen, ohne so etwas wie
    x * captlen + y
    rechnen zu müssen,
    so z.B. wie bereits oben erwähnt

    tMenu mymenu(10,20);
    strcpy(mymenu.list[5], "5 new testline", sizeof(testline));
    mymenu.list[5][0]='>';

  6. #6
    shedepe
    Gast
    Mein Vorschlag wäre: Mache eine Klasse, wie du sie jetzt schon hast. Lege aber die Instanzen des Klassen auf dem Stack an.
    Also statt tMenu * mymenu = new tMenu(); lieber tMenu myMenuy;

    Dann solltest du die Größen statt über den Konstruktor lieber als C++ Template übergeben. Dann können die zur Compilezeit ersetzt werden.
    Dann kannst du dein array auch mit: char mylist[x][y] anlegen.

    Beispiel
    Code:
    template <int x_size,int y_size>
    class Menu{
         private:
             char list[x_size][y_size];
         
    
    
    };
    
    Verwendung:
    Menu<10,20> myMenu;
    Noch ein Hinweis zum Rechnen (Falls das mal relevant für dich werden sollte):
    Einfach den Zugriff in einer Methode Kapseln die das Rechnen macht und dann ist das auch gar nicht so schlimm

Ähnliche Themen

  1. Change member of a class from another class
    Von iciwi im Forum Arduino -Plattform
    Antworten: 1
    Letzter Beitrag: 27.08.2016, 09:45
  2. neues Byte aus Byte-Array erstellen
    Von BoondockDuck im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 4
    Letzter Beitrag: 06.09.2008, 07:53
  3. Bits in sämtlichen Größen :)
    Von squelver im Forum Allgemeines zum Thema Roboter / Modellbau
    Antworten: 0
    Letzter Beitrag: 22.11.2007, 12:02
  4. SMD-Größen für SMD-Anfänger
    Von jeybo im Forum Elektronik
    Antworten: 22
    Letzter Beitrag: 29.08.2006, 07:04
  5. Eagle - Größen
    Von BlackDevil im Forum Konstruktion/CAD/3D-Druck/Sketchup und Platinenlayout Eagle & Fritzing u.a.
    Antworten: 9
    Letzter Beitrag: 27.03.2006, 22:58

Berechtigungen

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

12V Akku bauen