multidimensionale arrays in c++
-
Warum nur bedingt? Wieso erhalte ich dann eine korrekte Ausgabe ohne Segmentation Fault?
Bedingt, weil du den Pointer auf die erste "Tiefe" (int *ptr=arr[0][0];) setzt. Die nächste "Tiefe" (echt ein blödes Wort, hätte nicht ein 2d-Array gerreicht?
) kann sich irgendwo anders im Speicher befinden, da "new" ja den Speicher nicht hintereinander reserviert. Wenn es doch klappt, dann sollte das eigentlich Zufall bzw. wurde es ggf. vom Compiler so eingerichtet, dass es funktioniert.Falls ich hier Falschaussagen mache, möge mich bitte einer der Code-Gurus hier berichtigen.
Ansosnten sieht dein neuer Code eigentlich gut aus. Ich sehe da keinen direkten Fehler...
bnz
-
Hi, also ich hab mir jetzt deinen code mal angeschaut und wie es aussieht scheitert das ganze mMn an zeile 28:
delete[] arr[i][j];bis dahin läuft das programm, alle pointer und arrays werden ordnungsgemäß erstellt, gefüllt und ausgegeben aber an dieser einen stelle ist irgendwie der wurm drin. Kommentier mal die zeile aus dann wird alles laufen, frag mich aber nicht warum

-
Ich beziehe mich auf den allerersten post ganz oben.
-
Es hilft tatsächlich. Es ist zwar ziemlich eigenartig aber trotzdem vielen Dank.
Wenn mir nun noch jemand erklärt, wie man einen Pointer mit dem ersten Element eines dynamisch allozierten multidimensionalen arrays initialisiert, was nämlich zum Problem in Zeile 21 des zweiten Codes wird, gebe ich Ruhe.
Gute Nacht
-
Warum willst du das denn unbedingt mit pointern an dieser stelle machen?
Habe nochmal über das von mir beschriebene problem nachgedacht. Der grund dafür könnte zeile 18 sein:
int *ptr=arr[0][0];Du hast einen pointer der auf die elemente des arrays zeigt. Wenn dann die elemente gelöscht werden sollen, gibts ein problem. Das hört sich zwas spanisch an aber eine andere erklärung hab ich im moment dafür nicht. Hoffe das hilft dir nochmal weiter.
-
Jup, wenn ich *ptr entferne geht alles, es wird auch alles ordnungsgemäß gelöscht

-
Diese ganze Rumfrickelei mit Zeigern ist hochgrading fehleranfällig. In C mag man das ja vielleicht so machen, aber in C++ kann man mit relativ wenig Aufwand eine recht robuste Klasse daraus machen.
#include <vector> #include <cstddef> #include <stdexcept> template<typename T> class Array2D { std::size_t Rows_; // Anzahl Zeilen std::size_t Cols_; // Anzahl Spalten std::vector<T> Data_; // Inhalt public: Array2D() : Rows_( 0 ), Cols_( 0 ) { } Array2D( std::size_t Rows, std::size_t Cols ) : Rows_( Rows ), Cols_( Cols ), Data_( Rows * Cols ) { } T& operator()( std::size_t Row, std::size_t Col ) { if( Row < rows() && Col < cols() ) { return Data_[Row * cols() + Col]; } throw std::out_of_range( "Array index out of range" ); } const T& operator()( std::size_t Row, std::size_t Col ) const { if( Row < rows() && Col < cols() ) { return Data_[Row * cols() + Cols]; } throw std::out_of_range( "Array index out of range" ); } std::size_t rows() const { return Rows_; } std::size_t cols() const { return Cols_; } bool empty() const { return Data_.empty(); } std::size_t size() const { return Data_.size(); } void resize( std::size_t Rows, std::size_t Cols ) { Data_.resize( Rows * Cols ); Rows_ = Rows; Cols_ = Cols; } }; int main() { // erzeuge 0x0 Array, dann auf 5x3 vergrössern Array2D<int> a1; a1.resize( 5,3 ); // erzeuge 10x20 Array Array2D<int> a2( 10, 20 ); }Edit:
Mal durch den Compiler geschickt und Bugs entfernt
-
@ DocShoe:
ist zwar alles gut und schön was du sagst, aber bei mir z.B. wurden nie Vectoren dran genommen, also durften wir sowas auch nicht benutzen (wahrscheinlich weil es der Lehrer selbst nicht kann
).Also blieb uns nix anderes übrig als Pointer auf Pointer usw.
-
Na jut, dann will ich das mal durchgehen lassen...
Nach wie vor ist mein Einwand gültig, durch den Zugriff auf Rohzeiger landest du schneller in undefiniertem Verhalten als du gucken kannst. Selbst wenn du eine Lösung ohne std::vector schreiben musst kannst du die Zugriffe auf die Daten soweit kapseln, dass du robusten Code erhälst.
Wenn ihr std::vector nicht behandelt habt, dann hast du sicherlich auch noch nichts über templates gelernt, daher solltest du versuchen, eine 2D Array Klasse mit einem konkreten Datentyp zu programmieren. Den std::vector kann man durch 10 Zeilen weiteren Code ersetzen, lediglich die resize() Methode erfordert etwas mehr Aufmerksamkeit. Und du musst natürlich den Kopierkonstruktor und Zuweisungsoperator implementieren oder verbieten, aber das sind auch schon fortgeschrittene Themen.
Probier´s einfach mal, ist nicht so schwierig. Was man Programmieren unbedingt begreifen muss, ist dass robuster und leicht wartbarer Code wichtiger ist als irgendeine schnelle Lösung, die eher schlecht als recht funktioniert. Was du dir jetzt als Programmierstil aneignest wirst du später schwer wieder los.
-
Stimmt, wir hatten keine Vectoren und dementsprechend auch keine Templates.
Wir durften nicht mal strings benutzen, wir mussten alles schön in chars kloppen.
BTW: ich habe die Frage gar nicht gestellt, wollte dem Threadersteller nur mal zeigen wie es gehen könnte mit Pointer auf Pointer, und hab nur auf deine Aussage geantwortet dass es evtl. sein kann, so wie bei mir, das die das gar nicht benutzen dürfen.
