dynamische mehrdimensionale Arrays
-
Original erstellt von HumeSikkins:
Hallo,
Es gibt aber mehrere verschiedene Lösungen für dein Problem.
1. Wenn der Speicher nich am Stück sein muss, kannst du ein Array von Zeigern auf Arrays verwendenint main() { const int FirstDim = 4; const int SecDim = 5; // 1. Schritt: Dynamische Array von Zeigern anlegen: int** p2DimArr = new int*[FirstDim]; // 2. Schritt: An jeden Zeiger ein Array hängen for (int i = 0; i < FirstDim ; i++) p2DimArr[i] = new int[SecDim]; // mit dem neuen 2-dimensionalen Array arbeiten p2DimArr[0][0] = 42; //... // alles wieder löschen for (int j = 0; j < FirstDim ; j++) delete [] p2DimArr[j] ; delete [] p2DimArr; }
2. Wenn der Speicher am Stück sein muss, empfiehlt es sich das 2-dimensionale Array auf ein 1-dimensionales abzubilden:
class Simple2DimArr { private: int* pArr; int Rows, Cols; public: Simple2DimArr(int Zeilen, int Spalten) { Rows = Zeilen; Cols = Spalten; // 2-Dimensionales Array auf 1-Dimensionales abbilden pArr = new int[Rows * Cols]; } int* operator[](int Zeile) { // Array liegt "zeilenweise" im Speicher return & pArr[Zeile * Cols]; } ~Simple2DimArr() { delete [] pArr; } }; int main() { Simple2DimArr Arr(2,3); Arr[0][0] = 42; }
3. Einen dritten Weg eröffnet die Verwendung von Zeigern auf Felder.
Dieser Weg hat aber den Nachteil, dass nur wenige Leute mit deren Syntax vertraut sind:int main() { // Einen Zeiger auf ein Int-Array mit 5 Elementen anlegen int (*pArr)[5] = 0; // Den Zeiger auf ein zweidimensionales Array zeigen lassen. // Wichtig: Die zweite Dimension muss mit der Array-Größe // übereinstimmen, mit der der Zeiger deklariert wurde // pArr = new int [5][2]; wäre z.B. illegal, da ein Zeiger auf ein // Array mit 5 Elementen nicht in einen Zeiger auf ein Array mit // 2 Elementen konvertiert werden kann. pArr = new int[2][5]; pArr[0][0] = 42; // ... // Am Ende aufräumen nicht vergessen delete [] pArr; }
4. Der Weg für C++ Programmierer: Man verzichtet auf dynamische Arrays und verwendet stattdessen die Container der STL. Für den Anfang reichen vectoren. Wenn etwas schneller werden soll, bieten sich valarrays an:
#include <vector> using namespace std; int main() { const int FirstDim = 3; const int SecDim = 2; vector< vector<int> > My2DimArr(FirstDim); for (int i = 0; i < FirstDim; i++) My2DimArr[i].resize(SecDim); My2DimArr[1][1] = 42; }
Für den Spezialfall char-Arrays bietet sich die Klasse std::string aus der C++ Standardbibliothek an.
Original erstellt von Dimah:
Eine kleine Ergenzung zu Nr. 4.#include <vector> #include <cstddef> // für size_t using namespace std; template<typename T> void resize2DimVector(vector< vector<T> > & vec, size_t FirstDim, size_t SecDim) { vec.resize( FirstDim ); for(size_t i = 0; i < FirstDim; ++i) vec[i].resize( SecDim ); } template<typename T> const vector< vector<T> > make_2DimVector(size_t FirstDim, size_t SecDim) { vector< vector<T> > vec; resize2DimVector( vec, FirstDim, SecDim ); return vec; } template<typename T> void resize3DimVector(vector< vector< vector<T> > > & vec, size_t FirstDim, size_t SecDim, size_t ThirdDim) { vec.resize( FirstDim ); for (size_t i = 0; i < FirstDim; ++i) { vec[i].resize( SecDim ); for (size_t j = 0; j < SecDim; ++j) vec[i][j].resize( ThirdDim ); } } template<typename T> const vector< vector< vector<T> > > make_3DimVector(size_t FirstDim, size_t SecDim, size_t ThirdDim) { vector< vector< vector<T> > > vec; resize3DimVector( vec, FirstDim, SecDim, ThirdDim ); return vec; } int main() { vector< vector<int> > My2DimVec = make_2DimVector<int>( 100, 100 ); My2DimVec[47][11] = 13; resize2DimVector( My2DimVec, 333, 333 ); My2DimVec[222][222] = 1980; vector< vector< vector<int> > > My3DimVec = make_3DimVector<int>( 100, 100, 100 ); My3DimVec[4][71][1] = 42; resize3DimVector( My3DimVec, 200, 200, 200 ); My3DimVec[111][111][111] = 1337; }
Die make_ Funktionen sind nur auf Compilern zu empfehlen die, die named return value Optimierung Beherrschen.