-2

これは、常にクラッシュするコードの一部です。このクラッシュの理由がわかりません。私がしているのは、ループ内にいくつかのポインターを設定することだけです。このサイクルにコメントすれば、すべて問題ありません。変です..一番下のコードは、クラッシュが発生した場所です。デストラクタの名前と、プログラムがクラッシュする理由がわかりません。

    typedef std::set<IDrawable**> TDrawableList;
        typedef std::map<std::string, TDrawableList> THashLoad;
//  ...
    THashLoad::iterator itLoad =  gpMapRenderer->m_unloadedCells.find(file.substr(6, file.length()));
        if (itLoad != gpMapRenderer->m_unloadedCells.end())
        {
                TDrawableList::iterator itCells = itLoad->second.begin();
                TDrawableList::iterator itCellsEnd = itLoad->second.end();
                for (; itCells != itCellsEnd; ++itCells)
                {
                        **itCells = (IDrawable*)itHashPics->second.pImg;
                }

                gpMapRenderer->m_unloadedCells.erase(itLoad);  // < --- CRASH
        }
    // ... 
    // _construct.h
    // ...
template <class _Tp>
inline void _Destroy(_Tp* __pointer) {
# if _MSC_VER >= 1010
  __pointer;
# endif    // _MSC_VER >= 1000
# ifdef _STLP_TRIVIAL_DESTRUCTOR_BUG
  typedef typename __type_traits<_Tp>::has_trivial_destructor _Trivial_destructor;
  __destroy_aux(__pointer, _Trivial_destructor());
# else
#  if ( defined (__BORLANDC__) && ( __BORLANDC__ < 0x500 ) )
    __pointer->_Tp::~_Tp();
#  else
    __pointer->~_Tp(); // < ---- CRASH
#  endif
# endif
# ifdef _STLP_DEBUG_UNINITIALIZED
        memset((char*)__pointer, _STLP_SHRED_BYTE, sizeof(_Tp));
# endif
}

PS 私のプログラムはシングルスレッドです。

ありがとうございました。

アップデート:

class IDrawable
{
public:
    virtual ~IDrawable() {};

    virtual void Draw(const CIwSVec2& pos) = 0;
    virtual void Draw(const CIwSVec2& pos, const CIwSVec2& size) { IwAssert(IDRAWABLE, "Not Implemented");};
};

したがって、m_unloadedCells に追加する方法は次のとおりです。

void MapRenderer::AddCellToUnloadedList(const std::string& filename, IDrawable** pElement)
{
    THashLoad::iterator itLoad = m_unloadedCells.find(filename);
    if (itLoad != m_unloadedCells.end())
        itLoad->second.insert(pElement);
    else
    {
        std::set<IDrawable**> _set;
        _set.insert(pElement);
        m_unloadedCells.insert(make_pair(filename, _set));
    }
}

そしてコードのどこかに:

AddCellToUnloadedList(filenameToLoad, &itHashCells->second[index].drawingElement[i].pDrawable)

itHashcells:

typedef std::map<int, std::vector<Cell2> > THashCells;
THashCells itHashCells;

セル 2:

enum eDrawableType
{
    DTYPE_Sprite = 0,
    DTYPE_Animation
};

struct DrawingElement
{
    eDrawableType type;
    IDrawable* pDrawable;
};

struct Cell2
{
    Cell2()
    {
        drawingElement.reserve(10);
    }

    int location;
    int x, y;

    std::vector<DrawingElement> drawingElement;

    MinimapTileInfo minimap_tile_info[10];
};
4

1 に答える 1

0

問題は次の行にあるようです:

**itCells = (IDrawable*)itHashPics->second.pImg;

erase() にはありません。コメントアウトして見てみてください。
問題は、2 つのベクトル内のデータ構造へのポインターを初期化することだと思いますが、Cell2 に 10 個の要素を予約していることがわかりますが、10 個を超える要素が含まれていないか、itHashCells に十分に予約されているかは明確ではありません。したがって、そのベクターのいずれかに十分な要素を挿入してスペースを再割り当てすると、gpMapRenderer->m_unloadedCells のポインターが無効になります

時間をかけてコードをリファクタリングし、ポインターからポインターへの使用を避けるか、少なくともそれらを無効にしないデータ構造を使用することをお勧めします。現在の状態のコードは管理できません。

また、このコードを次のように書き換えることもできます。

void MapRenderer::AddCellToUnloadedList(const std::string& filename, IDrawable** pElement)
{
    THashLoad::iterator itLoad = m_unloadedCells.find(filename);
    if (itLoad != m_unloadedCells.end())
        itLoad->second.insert(pElement);
    else
    {
        std::set<IDrawable**> _set;
        _set.insert(pElement);
        m_unloadedCells.insert(make_pair(filename, _set));
    }
}

このように:

void MapRenderer::AddCellToUnloadedList(const std::string& filename, IDrawable** pElement)
{
    m_unloadedCells[ filename ].insert( pElement );
}

より読みやすく、少なくともオリジナルと同じくらい効果的だと思います。

于 2013-03-04T16:58:39.527 に答える