verschachtelter Vector


  • Mod

    Denksportler schrieb:

    Wenn ich jetzt z.B. für height den Wert 50 habe und für width den Wert 100, müsste der größte Index des vectors [49][99] sein. Allerdings ist momentan der größte Index [48][100], was so nicht ganz stimmt.
    Findet jemand den Fehler, denn für mich sieht der Code eigentlich korrekt aus.

    Wenn ich das richtig sehe wird beim ersten Durchlauf das temporäre Array nicht hinzugefügt, weil old und y beide 0 sind.

    Wenn du die Größen vorher schon alle kennst, dann kannst du aber auch die Größe der vectoren schon im Konstruktor oder mit resize, assign, fill, usw. festlegen und dann eine wesentlich einfachere Füllschleife schreiben als das was du jetzt hast. Ungefähr so (ungetestet, aber so als Idee):

    std::vector<std::vector<int> > array;
    array.assign(height, vector<int>(width));  // Array auf height x width dimensionieren
    for(int y = 0; y < height; y++)
        for(int x = 0; x < width; x++)
            array[y][x] = daten[y*width + x];
    

    edit: Rechen- und Rechtschreibfehler beseitigt (hoffentlich alle). Und Idee für etwas noch kürzeres:

    std::vector<std::vector<int> > array(height);
    for(int y = 0; y < height; y++)
       array[y] = vector<int>(daten+y*width, daten+(y+1)*width] );
    


  • Ich wusste garnicht das der '=' Operator auch bei vector funktioniert.
    Das funktioniert aber nur, wenn man den vector vorher dimensioniert oder?

    Jetzt habe ich aber noch eine andere Frage:
    Dieses Konstrukt:

    for(int y = 0; y < width; y++) {
    	for(int x = 0; x < height; x++) {
    		if (array[y][x] != 0) {
                // do something
            }
        }
    }
    

    liefer mir immer folgenden Fehler beim Debuggen:

    Eine Ausnahme (erste Chance) bei 0x004309b1 in Release.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xabababab.
    Unbehandelte Ausnahme bei 0x004309b1 in Release.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xabababab.
    

    in der 3. Zeile. Der Debugger sagt mir aber auch, dass alle Werte in dem vector korrekt belegt sind.


  • Mod

    Denksportler schrieb:

    Ich wusste garnicht das der '=' Operator auch bei vector funktioniert.

    Klar. Ist schließlich C++ und nicht C mit seiner komischen Sonderbehandlung von Arrays

    Das funktioniert aber nur, wenn man den vector vorher dimensioniert oder?

    Auf der linken Seite der Zuweisung muss ein gültiges Objekt stehen. Wie bei jeder Zuweisung.



  • Der Grund für die Exception ist der, dass in der Schleife der Wert y gar nicht zu existieren scheint. Auch nicht um Debugger. Woran liegt das?


  • Mod

    Denksportler schrieb:

    Der Grund für die Exception ist der, dass in der Schleife der Wert y gar nicht zu existieren scheint. Auch nicht um Debugger. Woran liegt das?

    Du meinst y ist nicht initialisiert? Vermutlich Tippfehler oder ähnliches. Zeig mal 1:1 die fraglichen Zeilen.



  • for(int y = 0; y < width; y++) {
    	for(int x = 0; x < height; x++) {
    		if (array[y][x] != 0) { // wirft die exception
    		}
    	}
    }
    

    So hat es vorher auch immer Funktioniert. Der Fehler trat erst auf, als ich den vector genommen habe.
    Wenn y nicht initialisiert wäre, stände im Debugger ja folgendes:

    Name: y
    Wert: ???
    

    Aber im Debugger steht gar nichts.



  • Du hast height und width vertauscht gegenüber SeppJ seinem Beispiel. Bei dir müsste es dann so aussehen

    std::vector<std::vector<int> > array(width, vector<int>(height));  // Array auf height x width dimensionieren
    for(int y = 0; y < width; y++)
        for(int x = 0; x < height; x++)
            array[y][x] = daten[y*width + x];
    

    Das assign braucht man auch nicht. Da reicht der Konstruktor.



  • Danke, so klappts... fast 😃
    Am Ende der Funtkion, also wenn der vector wieder zerstört wird, kommt jetzt dieser Fehler:

    HEAP[Release.exe]: Heap block at 00374D38 modified at 00374D7C past requested size of 3c
    Windows hat einen Haltepunkt in Release.exe ausgelöst.
    
    Dies kann auf eine Beschädigung des Heaps zurückzuführen sein, die auf ein Problem in Release.exe oder in einer der geladenen DLLs hinweist.
    
    Dies kann auch darauf zurückzuführen sein, dass der Benutzer F12 drückt, während Release.exe den Fokus hat.
    
    Weitere Analyseinformationen finden Sie möglicherweise im Ausgabefenster.
    

    Also F12 habe ich nicht gedrückt und ansonsten habe ich diese Fehlermeldung auch sonst nie gesehen.
    Mein Code sieht jetzt so aus:

    int width = daten[0];
    int height = daten[1];
    std::vector<std::vector<int> > maparray(width, std::vector<int>(height));
    for(int y = 0; y < height; y++) {
    	for(int x = 0; x < width; x++) {
    		maparray[y][x] = daten[y * width + x + 2];
    	}
    }
    for(int y = 0; y < width; y++) {
    	for(int x = 0; x < height; x++) {
    		if (maparray[y][x] != 0) {
    			// Daten verarbeiten
    		}
    	}
    }
    


  • Fällt dir der Unterschied an beiden for-Schleifen auf?



  • Ja, und der ist korrekt.
    Habs aber auch mal in allen anderen Variationen ausprobiert (auch wenns kein Sinn macht) und jedes mal der gleiche Fehler.



  • Denksportler schrieb:

    Ja, und der ist korrekt.

    Für width == height stimmt die Aussage wohl, aber das dürfte ein Sonderfall sein.



  • Wieso ist der korrekt? Der ist nur dann korrekt, wenn dein Array quadratisch ist.
    Im der ersten for-Schleifen Block läufst du mit y über die Höhe und x über die Breite, legst maparray aber mit width Zeilen zu je height Spalten an. Das kann doch nicht passen.
    Der zweite for-Schleifen Block ist in Ordnung, denn da läufst du mit y über die Breite und mit x über die Höhe, genau so, wie die Vektordimensionen initialisiert worden sind. Ob die erste Dimension jetzt die Höhe und die zweite die Breite ist oder umgekehrt weiß ich nicht.


Anmelden zum Antworten