Deklaration eines zweidimensionalen Arrays mit new
-
Ich habe versucht, ein zweidimensionales Array zu deklarieren, aber es ist wohl falsch:
int **array = new int[3][5];
Wie macht man's richtig?
Und was das Löschen betrifft: Würde
delete[] array;
oder muss man irgendwas von wegendelete[][] array;
machen?
-
Dynamische, zweidimensionale Arrays gibts nicht, man nimmt ein eindimensionales und berechnet dann jedesmal den Index mit
y*width+x
. Dann reicht auch ein stinknormalesdelete[]
.
Oder man verwendet Boost.MutiArray.
-
Hallo,
Schaut mal in die FAQ
http://www.c-plusplus.net/forum/39489
-
Wenn beide Dimensionen bekannt sind, reicht
int a[3][5];
Ist nur die innere bekannt, ginge
int (*a)[5] = new int[dim_x][5]; // ... delete[] a;
Ist keine bekannt, gibt es eine Reihe von Möglichkeiten. Boost hat eine Multi-Array-Bibliothek, die einen Blick wert sein dürfte, ansonsten wäre etwas in dieser Art eine einfache Möglichkeit:
#include <vector> template<typename T> class array2d { public: typedef T value_type; typedef value_type *pointer; typedef value_type const *const_pointer; typedef std::size_t size_type; array2d(size_type dim_x, size_type dim_y) : dim_y_(dim_y), data_(dim_x * dim_y) { } pointer operator[](size_type x) { return &data_[x * dim_y_]; } const_pointer operator[](size_type x) const { return &data_[x * dim_y_]; } private: size_type dim_y_; std::vector<value_type> data_; }; // ... array2d<int> a(x, y); // keine Freigabe notwendig (RAII)
-
seldon schrieb:
ansonsten wäre etwas in dieser Art eine einfache Möglichkeit:
pointer operator[](size_type x) { return &data_[x * dim_y_]; } const_pointer operator[](size_type x) const { return &data_[x * dim_y_]; }
Igitt!
Wenn dann lieber sowas:
typedef T value_type; typedef value_type &reference; typedef value_type const &const_reference; typedef std::size_t size_type; reference operator()(size_type x, size_type y) { return data_[y*dim_x_+x]; } const_reference operator()(size_type x, size_type y) const { return data_[y*dim_x_+x]; }
Siehe: http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.11
-
...der Text hinter dem Link besagt, dass der operator()-Ansatz für zerstreute Matrizen sinnvoller ist. Das ist zwar richtig, hat aber für diesen Anwendungsfall keinerlei Bedeutung.
-
Hier ein kleines Beispiel für ein 2D Array:
// Dynamic array 2D #include <iostream> #include <conio.h> using namespace std; double ** make2dFeld(int ,int ); void init2dFeld(double **,int,int); void show2dFeld(double **,int,int); void delete2dFeld(double **,int); int main() { int n,m,i,j; double **b; cout << " Eingabe Zeilen n : "; cin >> n; cout << " Eingabe Spalten m : "; cin >> m; b = make2dFeld(n,m); init2dFeld(b,n,m); show2dFeld(b,n,m); delete2dFeld(b,n); getch(); return 0; } //---------------------------------------------------------------------- double ** make2dFeld(int z,int s) { double **b; b = new (double* [z]); for (int i = 0; i < z; i++) { b[i] = new double[s]; } return b; } //---------------------------------------------------------------------- void init2dFeld(double **b,int z,int s) { for (int i = 0; i < z; i++ ) { for (int j = 0; j < s; j++) { b[i][j] = (i+1)*(j+1); } } } //---------------------------------------------------------------------- void show2dFeld(double **b,int z,int s) { for (int i = 0; i < z; i++ ) { for (int j = 0; j < s; j++) { cout<<b[i][j]<<','; } cout<<endl; } } //---------------------------------------------------------------------- void delete2dFeld(double **b,int z) { for (int i=0; i<z; i++) { delete [] b[i]; } delete [] b; }
-
make2dFeld
init2dFeld
show2dFeld
delete2dFeldEntweder Deutsch oder Englisch. Entscheide dich...
-
Denglisch schrieb:
make2dFeld
init2dFeld
show2dFeld
delete2dFeldEntweder Deutsch oder Englisch. Entscheide dich...
Troll wo anders!
-
Cybertec schrieb:
Troll wo anders!
Nur nicht gleich persönlich nehmen. Auch wenn es kein entscheidender Punkt ist: Dieses Bezeichnergemisch finde ich auch grauenhaft.
Aber um noch wichtigere Dinge zu nennen: Dein Code ist ziemlicher C-Style. Der Benutzer wird zu manueller Speicherverwaltung gezwungen. Er muss sich die Arraygrösse jeweils separat merken und hat beim Zugriff null Sicherheit. In einer Klasse gekapselt könnte man diese Probleme stark dezimieren.
Davon abgesehen ist es relativ ineffizient, viele kleine Allokationen für die Unter-Arrays zu haben (es sei denn, das Array ist wirklich gross). Wahrscheinlich wäre ein 1D-Array mit interner Indexumrechnung angebrachter.
Wenn kein wesentlicher Grund dagegen spricht, würde ich ohnehin getesteten Code wiederverwenden. Also
boost::multi_array
oder mindestensstd::vector
.
-
Der Code war noch aus meiner Schulzeit, und der Lehrer dort kennt kein vector, geschweige denn irgendwas aus der STL. Dort gibt es nur "C mit Klassen".
Wir mussten es so machen, auch wenn es sich unglaublich anhört.
Gut, die Namen hätten wirklich entweder deutsch oder englisch sein können, aber zur Demo ist es denk ich mal egal.
Und, sowas würde ich natürlich nie so machen.
-
Cybertec schrieb:
Der Code war noch aus meiner Schulzeit, und der Lehrer dort kennt kein vector, geschweige denn irgendwas aus der STL. Dort gibt es nur "C mit Klassen".
Wir mussten es so machen, auch wenn es sich unglaublich anhört.
Gut, die Namen hätten wirklich entweder deutsch oder englisch sein können, aber zur Demo ist es denk ich mal egal.
Und, sowas würde ich natürlich nie so machen.
Das ist leider bittere Realität... Aber dann solltest du es jetzt besser machen als dein Lehrer.
-
Der TE wollte doch aber wissen wie es funktioniert mit new und delete, und eigentlich dachte ich dass das Beispiel es gut zeigt.
Klar macht man das so nicht, das weis ich auch.
-
Ich tendiere auch zu einfachen Beispielen, jedoch erntet man dann immer viel Kritik
-
Cybertec schrieb:
Klar macht man das so nicht, das weis ich auch.
Genau da liegt das Problem. Du weisst, dass man es so nicht macht, zeigt es aber und verkaufst es, als würde man es genau so machen. Ein Anfänger kann diesen Unterschied nicht selber erkennen.
Grüssli
-
Dravere schrieb:
Cybertec schrieb:
Klar macht man das so nicht, das weis ich auch.
Genau da liegt das Problem. Du weisst, dass man es so nicht macht, zeigt es aber und verkaufst es, als würde man es genau so machen. Ein Anfänger kann diesen Unterschied nicht selber erkennen.
Grüssli
Jo, klar, nur wenn der TE fragt wie man einen string mit chars macht, dann erklär ich nicht wie es funktioniert mit std::string.
Naja, egal, das Beispiel war Mist, und jetzt sollte er wissen das man es SO nicht macht.