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 geschachteltenvector
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
-
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.
-
-
@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
beihttps
zu viel).Edit: Der richtige Link dazu ist Inhaltsverzeichnis des Magazins.
Auch weitere Links noch mithttp://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/
-
@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
beihttps
zu viel).Edit: Der richtige Link dazu ist Inhaltsverzeichnis des Magazins.
Auch weitere Links noch mithttp://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 nachmagazin.
durchsucht habe).Vllt. kannst du die letzten Beiträge in ein eigenes Thema unter "Forentechnik" abspalten?