在地图中擦除时崩溃(C ++)

时间:2013-03-04 15:39:46

标签: c++ stl

以下是始终崩溃的代码的一部分。我无法理解这次崩溃的原因。我所做的就是在循环中设置一些指针。如果我评论这个循环一切都会好的。这很奇怪..底部的代码是发生崩溃的地方。我无法得到析构函数的调用以及为什么我的程序会崩溃。

    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
}

P.S。我的程序是单线程的。

谢谢。

更新

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

1 个答案:

答案 0 :(得分:0)

问题似乎在这一行:

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

不在擦除()中。试着评论出去看看。
我认为问题是你初始化指向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 );
}

我认为它更具可读性,至少与原版一样有效。