2016-08-05 39 views
-3

Ich habe diese Frage für eine Weile jetzt recherchiert und ich denke, dass ich mein Problem eingegrenzt habe.Kann ntdll.dll nicht laden

Dies ist der Fehlerausgang

Critical error detected c0000374 
Duke's Army.exe has triggered a breakpoint. 

Exception thrown at 0x77E49841 (ntdll.dll) in Duke's Army.exe: 0xC0000374: A heap has been corrupted (parameters: 0x77E7C8D0). 
Unhandled exception at 0x77E49841 (ntdll.dll) in Duke's Army.exe: 0xC0000374: A heap has been corrupted (parameters: 0x77E7C8D0). 

The program '[14436] Duke's Army.exe' has exited with code 0 (0x0). 

Bezeichnen Sie Stapel als

ucrtbased.dll!0f8aa672() Unknown 
[Frames below may be incorrect and/or missing, no symbols loaded for ucrtbased.dll] 
[External Code] 
> Duke's Army.exe!Tile::Tile() Line 19 C++ 
[External Code] 
Duke's Army.exe!Map::Map(int w, int h) Line 70 C++ 
Duke's Army.exe!MapGenerator::init(int w, int h) Line 37 C++ 
Duke's Army.exe!MapGenerator::MapGenerator(int w, int h) Line 13 C++ 
Duke's Army.exe!PlayGameState::PlayGameState(Game * g) Line 13 C++ 
Duke's Army.exe!main() Line 11 C++ 
[External Code] 

Andere Antworten ein statisches Element empfehlen Entfernen folgt, ist die nicht richtig oder so etwas wie das erklärt wurde. In der (vermutlich) betroffenen Klasse gibt es jedoch einen statischen Vektor, den ich nicht entfernen kann. Irgendwelche Vorschläge?

[Dies ist die Klasse denke ich, die Fehler tritt aus]

Tile.h

class Tile 
{ 
public: 
    static std::vector<Tile> tiles; 

    // Constructors and methods... 

    // Method used in constructors to add to static tiles  
    void Tile::init(const std::string& n, const sf::Color& c) { 
     this->name = n; 
     this->color = c; 
     tiles.push_back(*this); 
    } 

    Tile(std::string n, sf::Color c) { 
     init(n, c); 
    }; 

    Tile() { 
     init("bounds", sf::Color::Black); 
    } 

    const static Tile wall; 
    const static Tile floor; 
    const static Tile bounds; 
    const static float TILE_SIZE; 
}; 

Static (Linie 19 in den Call-Stack der Beginn der Definition des Default-Konstruktor ist) Mitglieder sind in Tile.cpp erklärt

std::vector<Tile> Tile::tiles = std::vector<Tile>(3); 
const Tile Tile::wall("wall", sf::Color::White); 
const Tile Tile::floor("floor", sf::Color::Green); 
const Tile Tile::bounds; 
const float Tile::TILE_SIZE = 16.f; 
+0

Ich glaube nicht, das Problem in jedem Deklarationscode sein wird. Überprüfen Sie Ihre Konstruktoren und Methoden. –

+0

'const Tile Tile :: xxxx' sollte' const Tile :: xxxx' sein –

+1

@ Jean-FrançoisFabre Um. Ich denke nicht. Diese Mitglieder (drei davon) sind 'Tile'-Objekte, statisch für die Klasse' Tile' (was erlaubt ist). – WhozCraig

Antwort

3

Ihr Code Tile::tiles wie diese default-initialisiert:

std::vector<Tiles> Tile::tiles = std::vector<Tile>(3); 

Das Bau von vector nicht nur Kapazität gesetzt, erstellt es einen Vektor 3 Elemente enthält, Standard constructored, die in 3 Anrufe zu init führen wird, und in init Sie

tiles.push_back(*this); 

push_back Versuche um den Vektor um eins zu vergrößern und dann das neu hinzugefügte Element zu kopieren. Der Schlüssel hier ist wachsen Sie den Vektor.

Wieder: erinnern Sie sich, dies geschieht während der Konstruktion des Vektors.

Sie erstellen entweder ein neues Element jenseits der Zielgröße des Vektors oder überschreiben das aktuell aufgefüllte Element.

Die GNU-Implementierung von std :: vector legt die Vektorgröße erst fest, wenn der Konstruktor abgeschlossen ist. Als Ergebnis erhalten Sie Überschreibungen:

#include <iostream> 
#include <string> 
#include <vector> 

struct S { 
    std::string s_; 
    static std::vector<S> tiles; 

    S() { std::cout << "S()\n"; init("default"); } 
    S(const std::string& s) { 
     std::cout << "S(" << (void*) this << " with " << s << ")\n"; 
     init(s); 
    } 
    S(const S& rhs) { 
     std::cout << (void*) this << " copying " << (void*)&rhs << " (" << rhs.s_ << ")\n"; 
     s_ = rhs.s_; 
     s_ += " copy"; 
    } 

    void init(const std::string& s) { 
     s_ = s; 
     std::cout << "init " << (void*)this << " " << s_ << "\n"; 
     tiles.push_back(*this); // makes copy 
    } 
}; 


std::vector<S> S::tiles = std::vector<S>(3); 

int main() { 
    for (const auto& el : S::tiles) { 
     std::cout << el.s_ << "\n"; 
    } 
} 

Ausgänge http://ideone.com/0dr7L2

S() 
init 0x9e67a10 default 
0x9e67a10 copying 0x9e67a10() 
S() 
init 0x9e67a14 default 
0x9e67a14 copying 0x9e67a14() 
S() 
init 0x9e67a18 default 
0x9e67a18 copying 0x9e67a18() 
copy 
copy 
copy 

So UB stellen Sie bei der Inbetriebnahme Ihrer Anwendung.

Im obigen Beispiel initialisiert der Kopierkonstruktor standardmäßig sein Ziel, bevor die Kopie ausgeführt wird, und da es sich selbst kopiert, wird rhs.s_ gelöscht. Deshalb erhalten wir "copy" und nicht "default copy".

--- --- Bearbeiten

(ungültig, wie @underscore_d wies darauf hin)

--- Edit 2 ---

Die MSVC Vektor Implementierung tut dies:

explicit vector(size_type _Count) 
    : _Mybase() 
    { // construct from _Count * value_type() 
    if (_Buy(_Count)) 
     { // nonzero, fill it 
     _TRY_BEGIN 
     _Uninitialized_default_fill_n(this->_Myfirst(), _Count, 
      this->_Getal()); 
     this->_Mylast() += _Count; 
     _CATCH_ALL 
     _Tidy(); 
     _RERAISE; 
     _CATCH_END 
     } 
    } 

Der wichtigste Teil Wesen:

 _Uninitialized_default_fill_n(this->_Myfirst(), _Count, 
      this->_Getal()); 
     this->_Mylast() += _Count; 

Während der Füllung werden Ihre push_back's _MyLast um 3 Positionen erhöht, und dann die nächste Zeile des ctor wird _MyLast um 3 mehr inkrementieren.

Hier ist der gleiche Code von oben unter Visual Studio ausgeführt wird: http://rextester.com/WNQ21225

+0

@ user4581301 Ja - siehe auch meine Bearbeitung über Wand, Boden und Decke. – kfsone

+0

"Reihenfolge der Initialisierung ist nicht definiert" nur zwischen verschiedenen Übersetzungseinheiten. Diese 2 Variablen sind in einer einzigen TU definiert. In diesem Fall wird, wie bei allen anderen "statischen" Objekten, garantiert, dass die Reihenfolge der Initialisierung der Reihenfolge der Definition folgt. Dein letzter Abschnitt scheint irrelevant zu sein. –

+0

@ user4581301 Siehe Edit 2, zusammen mit einem Link zu einer Online-Visual Studio-Version des Testcodes. – kfsone