2

まず第一に、英語が下手で申し訳ありません。皆さんが私を理解してくれることを願っています:) WinAPIゲームを書いていますが、クラスの動作が非常に奇妙です.ベクトルを使用したすべての操作でプログラムがクラッシュするため、.exeが機能しなくなったとWindowsが言います. しかし、これらの行をデバッグすると、例外が発生します。

これは私のクラスヘッダーがどのように見えるかです:

#ifndef FIGURE_H_INCLUDED
#define FIGURE_H_INCLUDED

#include <vector>
#include <Windows.h>
#include "Other.h"

using namespace std;

enum Figure_Type { I, J, L, O, S, T, Z };

class Figure
{
public:
    /* CONSTRUCTORS */
    Figure();
    Figure(Figure_Type);

    /* MOVEMENT */
    bool                Move(vector<Cell>&, Direction&);
    void                Drop(vector<Cell>&);
    bool                Rotate(vector<Cell>&);

    /* OTHER */ 
    void                Draw(HDC&);

private:

    /* METHODS */   
    void                Generate();
    void                GenerateMasks();
    void                GenerateFigure();
    Figure              GetFigureCopy() const;  

    /* DATA */
    Shift               shift;
    char                mask[4][4];
    vector<Cell>        vCells;
    Figure_Type         type;
    int                 rotation;
};

#endif

私のコンストラクターは Generate() メソッドを使用しています。コードは次のとおりです。

void Figure::GenerateFigure()
{
    vCells.clear();
    int defPosX = 4,
            defPosY = 20;
    Cell    cell;

    for(int y = 0; y < 4; y++)
    {
        for(int x = 0; x < 4; x++)
        {
            if(mask[y][x] == '0')
            {
                cell.x = defPosX + x + shift.dx;
                cell.y = defPosY - y + shift.dy;
                vCells.push_back(cell);
            }
        }
    }
}

そして、vCells.clear() メソッドと (最初の行にコメントすると) vCells.push_back(cell) 行で例外が発生します。実際、ベクター/ベクター反復子を使用したすべての操作は、イテレーターをインクリメントしてもプログラムをクラッシュさせます。これらは最初のものであるため、コードはそれらの後に実行されなくなります。例外テキスト:

「Tetris_completely_new.exe の 0x5A4ACD2 (msvcp110d.dll) で未処理の例外: 0xC000041D: ユーザーのコールバック中に未処理の例外が発生しました。」

そして、これらの例外は、217 の「xutility」行でスローされます。私はそれをコメントしました:

....
// MEMBER FUNCTIONS FOR _Container_base12
inline void _Container_base12::_Orphan_all()
    {   // orphan all iterators
 #if _ITERATOR_DEBUG_LEVEL == 2
    if (_Myproxy != 0)
        {   // proxy allocated, drain it
        _Lockit _Lock(_LOCK_DEBUG);

        for (_Iterator_base12 **_Pnext = &_Myproxy->_Myfirstiter;
            *_Pnext != 0; *_Pnext = (*_Pnext)->_Mynextiter)
            **(*_Pnext)->_Myproxy = 0;**    // <------------ THIS LINE
        _Myproxy->_Myfirstiter = 0;
        }
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
    }
....

私のCell 構造体は次のようになります。

struct Cell
{
    Cell() : x(1), y(1) { }
    Cell(int _x, int _y): x(_x), y(_y) { }

    void Draw(HDC&) const;

    bool operator ==(const Cell& a) const { return (x == a.x && y == a.y); } 
    bool operator !=(const Cell& a) const { return !(*this == a); } 

    int x;
    int y;
};

そしてFigure コンストラクター:

Figure::Figure()
{
    srand(time(NULL));

    vCells.clear();
    type = Figure_Type(rand() % 7);
    rotation = 0;
    shift.dx = 0;
    shift.dy = 0;

    Generate();
}
4

1 に答える 1

1

未定義の動作を呼び出している可能性があります。

これ以上の情報がなければ、古いオブジェクト参照/ポインターを介してインスタンス メソッドを呼び出していると思います (コールバック登録時に取得された参照は無効になりますか?)。

また、現在質問に書かれているように、あなたは の単位化されたバイトに基づいて図を生成しているmaskので、これらも初期化する必要があるでしょう。

これは、少し近代化/クリーンアップされたバージョンの例です。ノート

  • 初期化子リストの使用
  • 均一な初期化
  • 並べ替えられたメンバーの初期化
  • using namespaceヘッダーで使用しない
  • コンストラクターの代わりに移動srandしましたmain

Coliruでライブを見る

#ifndef FIGURE_H_INCLUDED
#define FIGURE_H_INCLUDED

#include <vector>

#ifdef _WIN32
#   include <Windows.h>
#   include "Other.h"
#else
#   include <cstdint>
#   include <cstdlib>
#   include <ctime>

using HDC = uint32_t;
#endif

struct Cell
{
    Cell(int _x=1, int _y=1): x(_x), y(_y) { }

    void Draw(HDC&) const;

    bool operator ==(const Cell& a) const { return (x == a.x && y == a.y); }
    bool operator !=(const Cell& a) const { return !(*this == a); }

    int x;
    int y;
};

struct Shift
{
    Shift(int dx=0, int dy=0) : dx(dx), dy(dy) {}
    int dx, dy;
};

enum class Direction
{
    up, down, left, right
};

enum Figure_Type { I, J, L, O, S, T, Z };

class Figure
{
public:
    /* CONSTRUCTORS */
    Figure();
    Figure(Figure_Type);

    /* MOVEMENT */
    bool        Move(std::vector<Cell>&, Direction&);
    void        Drop(std::vector<Cell>&);
    bool        Rotate(std::vector<Cell>&);

    /* OTHER */
    void        Draw(HDC&);

private:

    /* METHODS */
    void        Generate();
    void        GenerateMasks();
    void        GenerateFigure();
    Figure      GetFigureCopy() const;

    /* DATA */
    char        mask[4][4];
    std::vector<Cell> vCells;
    Figure_Type  type;
    int         rotation;
    Shift       shift;
};

#endif

/*
 * And I'm getting exceptions on vCells.clear() method and (if I comment first
 * line) vCells.push_back(cell) line. Actually every operation with vector /
 * vector iterators crash my program even incrementing iterator, those are just
 * the first so my code isn't running any longer after them.
 *
 * Exception text:
 * **"Unhandled exception at 0x5A4ACCD2 (msvcp110d.dll) in
 *    Tetris_completely_new.exe: 0xC000041D: An unhandled exception was
 *    encountered during a user callback."**
 *
 * And these exceptions are thrown on 217's line of "xutility". I commented it:
 *
 *   ....
 *   // MEMBER FUNCTIONS FOR _Container_base12
 *   inline void _Container_base12::_Orphan_all()
 *     { // orphan all iterators
 *    #if _ITERATOR_DEBUG_LEVEL == 2
 *     if (_Myproxy != 0)
 *       { // proxy allocated, drain it
 *       _Lockit _Lock(_LOCK_DEBUG);
 *
 *       for (_Iterator_base12 **_Pnext = &_Myproxy->_Myfirstiter;
 *         *_Pnext != 0; *_Pnext = (*_Pnext)->_Mynextiter)
 *         **(*_Pnext)->_Myproxy = 0;**    // <------------ THIS LINE
 *       _Myproxy->_Myfirstiter = 0;
 *       }
 *    #endif // _ITERATOR_DEBUG_LEVEL == 2
 *     }
 *   ....
 *
 * Here is how my **Cell struct** looks like:
 */

//And **Figure constructor**:

Figure::Figure()
  : mask {{0}},
    vCells(),
    type((Figure_Type) (rand() % 7)),
    rotation(0),
    shift({0,0})
{
    Generate();
}

//My constructors are using Generate() method, which code is:
void Figure::Generate()
{
    GenerateFigure();
}

void Figure::GenerateFigure()
{
    vCells.clear();
    for(int y = 0; y < 4; y++) {
        for(int x = 0; x < 4; x++) {
            if(mask[y][x] == '0')
                vCells.push_back({4 + x + shift.dx, 20 - y + shift.dy});
        }
    }
}

int main()
{
    srand(time(0));
    Figure fig1;
    Figure fig2;
}
于 2013-09-22T19:37:46.477 に答える