2016-08-05 24 views
-3

私はこの質問をしばらく調査しましたが、問題を絞り込んだと思います。ntdll.dllを読み込めません

これは

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] 

他の回答を以下のようにエラー出力

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). 

コールスタックがあるが、適切に宣言されていない静的メンバまたはそれに似たものを取り除く示唆しています。しかし、(想定される)影響を受けるクラスには、削除する方法が見つからない静的なベクトルがあります。助言がありますか?

[これは私がエラーが発生したからだと思うクラスである] (コールスタック内ライン19は、デフォルトコンストラクタの定義の始まりである)

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; 
}; 

静的メンバーは

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

私は問題は任意の宣言コードであることを行っているとは思いません。コンストラクタとメソッドを確認してください。 –

+0

'constタイルタイル:: xxxx'は' const Tile :: xxxx'でなければなりません –

+1

@ Jean-FrançoisFabreUm。私はそうは思わない。それらのメンバー(そのうち3つ)は 'Tile'クラスに静的な' Tile'オブジェクトです(許可されています)。 – WhozCraig

答えて

3

あなたのコードのこのようなTile::tilesデフォルトは、初期化Tile.cppで宣言されています。

vectorの建設だけで容量を設定していないこと
std::vector<Tiles> Tile::tiles = std::vector<Tile>(3); 

は、それがinitに3つの呼び出しになりますこれ、デフォルトはconstructored、3つの要素を含むベクトルを作成し、initであなた

tiles.push_back(*this); 

push_backの試みベクトルを1つ増やして、新たに追加された要素をコピー構築します。ここの重要な部分はベクトルを成長させます。

ここでもまた、これはベクトルの構築中に起こっていることを覚えておいてください。

ベクトルのターゲットサイズを超えて新しい要素を作成するか、または現在挿入されている要素を上書きします。

std :: vectorのGNU実装では、コンストラクタが完了するまでベクターサイズが設定されません。その結果、あなたは上書きを取得:だから、あなたのアプリケーションの起動時にUBを導入している

#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"; 
    } 
} 

出力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 

上記の例では、コピーコンストラクタはコピーを実行する前にターゲットをデフォルトで初期化します。コピー自体はコピーされているため、rhs.s_がクリアされます。これが「copy」で、「default copy」ではありません。

---編集---

(無効、@underscore_dによって指摘されるように)

---編集2 ---

MSVCベクトルの実装がこれを行う:

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 
     } 
    } 

キーパーツビーイング:

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

塗りつぶし中、push_backの値は_MyLastに3桁増え、ctorの次の行は_MyLastに3増えます。ここで

は、Visual Studioの下で実行されている上から同じコードです:http://rextester.com/WNQ21225

+0

@ user4581301はい - 壁、床、天井についての私の編集も見てください。 – kfsone

+0

異なる翻訳単位間の "初期化の順序は不定"です。これら2つの変数は、単一のTUに定義されています。その場合、他の 'static'オブジェクトと同様に、初期化の順序は定義の順番に従うことが保証されます。あなたの最後のセクションは無関係です。 –

+0

@ user4581301編集2を参照し、テストコードのオンラインビジュアルスタジオ版へのリンクを参照してください。 – kfsone

関連する問題