2013-09-22 161 views
1

首先對不起我的英文不好,希望你們能理解我:)編寫WinAPI遊戲和我的類的行爲非常奇怪:所有操作與向量 崩潰我的程序,所以Windows說我的.exe停止工作。但是,當我調試這些行 我收到異常。C++ std ::向量迭代器錯誤

這是我的類的頭看起來像:

#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 

我的構造函數使用生成()方法,它的代碼是:

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)行。實際上,每次使用矢量/矢量迭代器的操作都會使我的程序崩潰,甚至會增加迭代器,這些只是第一次,所以我的代碼不再運行。 異常文本:

「未處理的異常在0x5A4ACCD2(msvcp110d.dll)在Tetris_completely_new.exe: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 */ 
    } 
.... 

這裏是我的細胞結構的樣子:

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() 
{ 
    srand(time(NULL)); 

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

    Generate(); 
} 
+0

我想看看Cell類的內存分配/釋放。 – user2672165

+0

可以請你展示一段可以用於再現你的問題的代碼 – AnatolyS

+0

你的當前代碼看起來不錯,錯誤是其他地方 – billz

回答

1

你很可能會調用未定義的行爲。

沒有更多的信息,我會說你通過陳舊的對象引用/指針調用實例方法(在回調註冊時引用的引用不再有效?)。

此外,正如目前在問題中所寫的,您正在生成一個基於mask中單位字節的數字,因此您可能還想對它們進行初始化。

這是一個輕微的現代化/清理版本。注意

  • 使用初始化列表
  • 統一初始化
  • 重新排序成員初始化
  • 在頭不使用using namespace
  • 移動srandmain,而不是構造

看到它Live on 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; 
}