Mehrdimensionaler Vector



  • Hey Leute,

    ich habe folgendes Problem. Ich brauche ein 2-dimensionales dynamisches Array, dafür möchte ich einen vector nutzen. Das ist doch möglich, oder?

    Initialisierung

    vector< vector<int> > m_arr;
    

    Ist die Init. so richtig? Wenn ja, wie spreche ich nun die verschiedenen Dimensionen des vectors an? Und speichere was an die entsprechende Stelle.

    Alle "Lösungen" die ich per Google gefunden habe, bringen mir einen Linker-Error, ähnlich dem hier.

    error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp___CrtDbgReportW" in Funktion ""public: __thiscall std::_Vector_const_iterator<class std::vector<int,class std::allocator<int> >,class std::allocator<class std::vector<int,class std::allocator<int> > > >::_Vector_const_iterator<class std::vector<int,class std::allocator<int> >,class std::allocator<class std::vector<int,class std::allocator<int> > > >(class std::vector<int,class std::allocator<int> > *,class std::_Container_base_secure const *)" (??0?_Vector_const_iterator@V?\_Vector\_const\_iterator@V?vector@HV?allocator@H@std@@@std@@V?allocator@H@std@@@std@@V?allocator@V?vector@HV?vector@HV?allocator@H@std@@@std@@@2@@std@@QAE@PAV?vector@HV?vector@HV?allocator@H@std@@@1@PBV_Container_base_secure@1@@Z)".



  • Das ist so grundsätzlich korrekt.

    Die Dimensionen sind noch nicht gesetzt. Du musst erst noch welche einfügen. Also in etwa so:

    m_arr.push_back ( vector<int> ( 5 ) ); // einen vector mit 5 Elementen einfügen
    

    Das kannst du bereits bei der Initialisierung machen.

    Der Linkerfehler hat mit dem gezeigten Code nicht viel zu tun. Zeig mal ein komplettes Beispiel, wo der Fehler kommt.



  • Hey,

    ich habe folgende Klasse.

    Header:

    #include <vector>
    
    using namespace std;
    
    class Map
    {
    	int height;
    	int width;
    
    	vector<vector<int> > m_arr;
    public:
    	Map(int height, int width);
    	~Map(void);
    };...
    

    CPP

    #include "Map.h"
    
    Map::Map(int height, int width)
    {
    	this->height = height;
    	this->width = width;
    
    	m_arr.push_back( vector<int> (5));
    }...
    

    Und selbst hier kommt schon der besagte Linker Error, und das obwohl nicht mehr mit dem vector gemacht wird 😞
    Benutze das Visual Studio von MS.

    Ich kann doch vectoren als Member-Variablen nutzen, oder?



  • Ok. Der Fehler liegt nicht am Code. Am besten erstellst du das gesamte Projekt neu. (Also in der IDE das komplette Projekt neu builden lassen, nicht neu coden. ;))

    Ein paar Mängel am Code hat es aber.

    1. using namespace gehört nicht in einen Header!
    2. Nutze Initialisierungslisten

    Map::Map(int height, int width)
    : // start der Initialisierungsliste
    height ( height ),
    width ( width )
    {
        m_arr.push_back( vector<int> (5)); // das könntet du auch bereits im Konstruktor von m_arr machen.
    }
    


  • huhu dropthelie

    also das hier geht bei mir problemlos:

    #include <iostream>
    #include <vector>
    using namespace std;
    
    class Map
    {
        private:
            int height;
            int width;
            vector< vector<int> > m_arr;
    
        public:
            Map(int height, int width);
    };
    
    Map::Map(int height, int width)
    {
        this->height = height;
        this->width = width;
    
        m_arr.push_back( vector<int>(5) );
    }
    
    int main()
    {
        system("pause>nul");
        return 0;
    }
    

    PS: Wenn du MS VS benutzt, musst du allerdings noch die Header-Datei "stdafx.h" einbinden glaube ich 😉



  • Ok, hab das Projekt neu angelegt... jetzt gehts!

    Hab vorhin die SDL Bibliothek eingebunden, dafür müssen ja einige Änderungen an den Projekteinstellungen vorgenommen werden. Evtl. lags daran.

    So, nun noch ein paar Fragen.

    Wo sollte man den namespace sonst festlegen?
    Und wie kann ich die n-Element des vectors im Konstruktor anlegen? Muss ich dazu nicht die Header verändern? Geht das auch wenn der Vector eine variable Grösse haben soll, es soll sich ja an den Werten height und width orientieren.

    Und das Wichtigste wie schreibe ich jetzt in den Vector, z.B. im Feld [2][4] den Wert 42?

    Wir haben in der Vorlesung (2. Sem) vectoren zwar ein wenig angekratzt, meistens waren die Beispiele nur Eindimensional. Daher entschuldigt meine Unwissenheit. Von Initialisierungslisten hab ich leider auch noch nichts gehört 😞 Aber gut zu wissen, dass es sowas gibt 😃

    @Dweb: MS VS konnt die Datei leider nicht includen, da sie nicht gefunden wurde. Trotzdem danke 😃



  • dropthelie schrieb:

    So, nun noch ein paar Fragen.
    Wo sollte man den namespace sonst festlegen?
    @Dweb: MS VS konnt die Datei leider nicht includen, da sie nicht gefunden wurde. Trotzdem danke 😃

    Könnte schwören MS VS braucht diese header:D naja...

    Nun zu deiner 1. Frage:

    "using namespace std" kommt nicht in die header,
    weil man, für jemanden der jetzt zum Beispiel deine Header benutzen will,
    nicht den gesamten Namensraum "std" offenlegen will.
    --> Eventuell benötigt derjenige "namespace std" ja überhaupt gar nicht.

    D.h. wenn du "namespace std" brauchst, legst du dies in deiner cpp-File fest.



  • dropthelie schrieb:

    Und das Wichtigste wie schreibe ich jetzt in den Vector, z.B. im Feld [2][4] den Wert 42?

    Wenn du dein vector mal genügend gross angelegt hast, kannst du darauf ganz normal (als wäre es ein mehrdimensionales Array) zugreifen.

    m_arr[2][2] = 42;
    

    Aber eben du musst (in dem Beispiel oben) mindestens 3 Reihen und 3 Spalten haben. Also 3 mal ein vector<int> mit je mindestens 3 Elementen eingefügt haben.

    DWeb schrieb:

    Könnte schwören MS VS braucht diese header:D naja...

    Nur, wenn du natürlich vorkompilierte Header brauchst. Ansonsten natürlich nicht. 😉



  • Warum kam in diesem Thread noch nicht der Vorschlag, intern nur ein 1d-Array zu haben und das ganze dann einfach zu wrappen? Ist sonst immer bei den ersten 5 Posts mind. 2 mal vertreten^^
    Ist aber vermutlich wirklich eine tolle Idee 😛

    bb



  • Hi,

    also soweit funktioniert es mit den 2 Dim. Wie würde das anlegen eines dreidimensionales vectors aussehen?

    Habe mir gedacht, dass es etwas in Richtung (s. u.) sein müsste.

    m_arr.push_back(vector<vector<int> (depth)> (width));
    

    @unskilled: Habe ich mir auch schon überlegt, allerdings ist es imo ziemlich unübersichtlich, vorallem wenn man ein [1000][1000] Vector hätte.

    Danke an alle 😃



  • dropthelie schrieb:

    @unskilled: Habe ich mir auch schon überlegt, allerdings ist es imo ziemlich unübersichtlich, vorallem wenn man ein [1000][1000] Vector hätte.

    Nein, das ist nicht unübersichtlich. Du musst ja nur beim Elementzugriff drauf achten. Wenn du eine fertige Lösung willst, die soetwas macht, dann schau dir Boost.MultiArray an.

    Du sparst dir auf jeden Fall den ganzen unnötigen Verwaltungsoverhead, den du bei vector<vector<T>> hast.


Log in to reply