C++ 2d_Arrays Zeilen mit dynamischer Länge erstellen



  • Ich habe mal eine Verständnisfrage zu 2dim Arrays. Es ist ja möglich, es einerseits über einen Pointer zu erstellen, haben dann quasi eine Liste, wo alle Werte hintereinander erstellt werden, oder aber ein Pointer Array auf Pointer, wie hier im unteren Beispiel, in welchem ich für jede Zeile die Anzahl der Elemente festlegen kann (Also die Speichermenge, welche ich allokiere). Ich hab im Netz ein Beispiel gefunden, schnalle aber nicht, was muss ich ändern, wenn ich z.B. 3 Zeilen, 3 Spalten habe, der ersten Zeile 1 Element, der zweiten 2 Elemente, und der 3 3 Elemente zuweisen möchte. Hoffe, ich darf das hier fragen, auch wenn es sich nicht direkt auf den C++ Kurs bezieht.
    Hier der Code:
    #include <cstring>
    #include <iostream>

    // print the 2D array
    void print_2d_array(int **multi_dim_array, int row, int cole)
    {
    for (int i = 0; i < row; i++)
    {
    for (int j = 0; j < cole; j++)
    {
    std::cout << multi_dim_array[i][j] << " ";
    }
    std::cout << std::endl;
    }
    }

    void assign_values(int **multi_dim_array, int row, int cole)
    {
    // assign values to the allocated memory
    for (int i = 0; i < row; i++)
    {
    for (int j = 0; j < cole; j++)
    {
    multi_dim_array[i][j] = rand() % 100;
    }
    }
    }

    // Dynamically allocate memory for 2D Array in C++
    int main()
    {

    // Array-of-Pointer-Arithmetic of Size-MM for 2D Array. Then dynamically allocate memory
    // size N for each row. --> Dynamic Memory Allocation in C++ for 2D Array
    // `MM × NN` matrix
    int MM;
    int NN;
    
    std::cout << "Anzahl Zeilen: ";
    std::cin >> MM;
    
    std::cout << "Anzahl Spalten: ";
    std::cin >> NN;
    
    // dynamically create an array of pointers of size `M`
    int **B = new int *[MM];
    
    // dynamically allocate memory of size `N` for each row
    for (int i = 0; i < MM; i++)
    {
        B[i] = new int[NN];
    }
    assign_values(B, MM, NN);
    
    
    print_2d_array(B, MM, NN);
    
    
    // deallocate memory using the delete[] operator
    for (int i = 0; i < MM; i++)
    {
        delete[] B[i];
    }
    delete[] B;
    
    
    return 0;
    

    }



  • In modernem C++ hantiert man nicht mehr mit rohen Zeiger, ich habe vor ein paar Jahren mal was zu 2D Arrays geschrieben, vllt. hilft dir das:
    https://www.c-plusplus.net/forum/topic/348029/array2d-evolution-von-manueller-speicherverwaltung-zur-stl



  • Ich hab im Netz ein Beispiel gefunden,

    hm... das ist nicht unbedingt immer eine gute Idee. Dein Beispielcode solltest du so nicht schreiben (benutze bitte kein rohes new / delete, siehe R11 und R60.

    Die Anforderung "jede Zeile soll unterschiedlich viele Spalten haben" steht ja irgendwie im Kontrast zu einem 2d-Array - das hat ja gerade in jeder Zeile gleich viele Elemente.

    Um im Wesentlichen bei deiner Datenstruktur zu bleiben, würde ich erstmal auf einen std::vector<std::vector<double>> umstellen. Dann geht die manuelle Speicherverwaltung weg und du kannst in jeder Zeile unterschiedliche Längen haben. (aber nenne es nicht mehr 2d-Array).

    Siehe https://en.cppreference.com/w/cpp/container/vector
    Der vector kennt seine Länge auch schon selbst.

    Zusätzlich zu der ganzen Speicherproblematik in deinem Programm kommt ja noch, dass du auch die Längen der einzelnen Zeilen irgendwo speichern müsstest. (Es sei denn, du hast eine Dreiecksmatrix, dann ginge das logischerweise auch anders)



  • Um noch etwas den Ausführungen von @wob hinzuzufügen:

    Ein Array ist ein zusammenhängender Speicherbereich, per Definition. Wenn beide Dimensionen zur Laufzeit ihre Größe ändern sollen ist das kein Array mehr.



  • @wob sagte in C++ 2d_Arrays Zeilen mit dynamischer Länge erstellen:

    Zusätzlich zu der ganzen Speicherproblematik in deinem Programm kommt ja noch, dass du auch die Längen der einzelnen Zeilen irgendwo speichern müsstest. (Es sei denn, du hast eine Dreiecksmatrix, dann ginge das logischerweise auch anders)

    Leicht abschweifend: Echt ein Jammer, dass diese Information eliminiert und vor dem User versteckt wird. Die new/ delete[]-Implementierung muss ja schliesslich wissen, wie viele Objekte später zu dekonstruieren sind. In der Praxis sieht das dann so aus, dass die Länge tatsächlich gespeichert wird (meist an einer Adresse vor dem zurückgegebenen Pointer), aber man keinen Zugriff auf diese Information hat.

    Das delete[] muss dann auch noch die Länge auslesen, mit einem zusätzlichen Speicherzugriff auf den reservierten Heap (statt auf den Stack, der oft bereits "heiß" im Cache liegt). Alles in allem ein ziemliches Gefrickel und noch ein Grund mehr, einen geschachtelten vector zu nehmen, wie du vorgeschlagen hast: Der kennt seine Länge, teilt sie auf Anfrage mit und muss dafür auch nicht extra auf den Nutzdaten-Speicherbereich zugreifen.

    ... nur um mal ein bisschen mit dem Missverständnis aufzuräumen, dass diese (dynamischen) lowlevel-C-Arrays irgendwie "effizienter" sein könnten, weil die scheibar keine Abstraktion drumherum haben.



  • Dankeschön für die sehr ausführlichen Antworten. Ich bin eindeutig blutiger Anfänger mit C++, auch wenn ich schon in Python programmiert habe. Daher bin ich dankbar für die vielseitigen Anregungen hier. Ich werde mich nun mit dem "vector" beschäftigen. Ich habe aus den Poasts hier zwei wertvolle Seiten zum Nachschlagen erhalten: 1) en.cppreference.com 2) C++ Core Guidelines
    Da ich mir C++ autodidaktisch mit mehreren Udemy-Kursen reinziehe: Gibt es gute Nachschlagewerke für C++, welche Ihr mir ans Herz legen würdet???
    Und - Danke für dieses tolle Forum hier, mit soviel Input hatte ich nicht gerechnet.
    Gruß Ingo


  • Mod

    Die beiden Standardreferenzen sind en.cppreference.com (kennst du schon) und cplusplus.com. Die haben zwar auch beide einen kleinen Teil, wo die Sprache an sich erklärt wird, aber sie ersetzen nicht wirklich ein Lehrbuch. Solche Nachschlagewerke sind für Leute gedacht, die schon wissen was sie tun, aber nicht die gesamte Standardbibliothek auswendig können.



  • Schau einfach mal in die Linkliste.

    Online kann ich dir auch Learn C++ zum Einstieg empfehlen.


  • Mod

    @Th69 sagte in C++ 2d_Arrays Zeilen mit dynamischer Länge erstellen:

    Schau einfach mal in die Linkliste.

    Da hätte ich mal eine spontane Frage an einen Nichtmoderator: Kann man die Links zum Magazin eigentlich lesen? Denn das Magazin liegt in einem archivierten Teil des Forums, von dem ich nicht sicher bin, ob er für die Öffentlichkeit überhaupt zugänglich ist. Wenn nicht, würde ich den Abschnitt entfernen, ist ja sowieso alles auf prä-C++11 Stand.



  • Das Inhaltsverzeichnis des Magazins kann man nicht aufrufen, aber die darunterstehenden Artikel schon (nur beim ersten ist ein Fehler in der URL: da ist ein h bei https zu viel).

    Edit: Der richtige Link dazu ist Inhaltsverzeichnis des Magazins.
    Auch weitere Links noch mit http://magazin.c-plusplus.net/artikel (bei "GUI-Programmierung") sind nicht aufrufbar, aber über das Inhaltsverzeichnis auffindbar (bzw. dessen URLs müßten dann dort verwendet werden).



  • @Ingolf_008 sagte in C++ 2d_Arrays Zeilen mit dynamischer Länge erstellen:

    Gibt es gute Nachschlagewerke für C++, welche Ihr mir ans Herz legen würdet???

    https://en.cppreference.com/w/
    https://cplusplus.com/reference/


  • Mod

    @Th69 sagte in C++ 2d_Arrays Zeilen mit dynamischer Länge erstellen:

    Das Inhaltsverzeichnis des Magazins kann man nicht aufrufen, aber die darunterstehenden Artikel schon (nur beim ersten ist ein Fehler in der URL: da ist ein h bei https zu viel).

    Edit: Der richtige Link dazu ist Inhaltsverzeichnis des Magazins.
    Auch weitere Links noch mit http://magazin.c-plusplus.net/artikel (bei "GUI-Programmierung") sind nicht aufrufbar, aber über das Inhaltsverzeichnis auffindbar (bzw. dessen URLs müßten dann dort verwendet werden).

    Danke! Ich habe korrigiert, was du und ich finden konnten.



  • Ein paar Mal sind immer noch http://magazin.c-plusplus.net/inhaltsverzeichnis referenziert (habe ich gefunden, indem ich den Seitenquelltext nach magazin. durchsucht habe).

    Vllt. kannst du die letzten Beiträge in ein eigenes Thema unter "Forentechnik" abspalten?


Anmelden zum Antworten