如何知道析构函数中的堆栈损坏?

时间:2012-04-12 12:09:42

标签: c++ memory gcc c++11 memory-corruption

从现在开始,我一直面临着一个问题,但我没有找到解决方案:(

我有一个这样的课程:

template<typename Node, unsigned int Threads, unsigned int Size = 2, unsigned int Prefill = 50>
class HazardManager {
    public:
        HazardManager();

        HazardManager(const HazardManager& rhs) = delete;

        /* Some methods */

    private:
        Node* Pointers[Threads][Size];

        std::list<Node*> LocalQueues[Threads];
        std::list<Node*> FreeQueues[Threads];

        /* Some private methods */
};

此类在另一个类中使用:

template<typename T, int Threads>
class AVLTree {
    public:
        AVLTree();
        ~AVLTree();

    private:
        Node* rootHolder;

        HazardManager<Node, Threads, 3> hazard;

        unsigned int Curren[Threads];
};

AVLTree类在堆栈上分配。当AVLTree被破坏时,我在std :: list析构函数中遇到了分段错误。这是valgrind的输出:

==9336== Invalid read of size 8
==9336==    at 0x419F69: std::_List_base<avltree::Node*, std::allocator<avltree::Node*> >::_M_clear() (list.tcc:74)
==9336==    by 0x419645: std::_List_base<avltree::Node*, std::allocator<avltree::Node*> >::~_List_base() (stl_list.h:401)
==9336==    by 0x418DF9: std::list<avltree::Node*, std::allocator<avltree::Node*> >::~list() (stl_list.h:458)
==9336==    by 0x418E66: HazardManager<avltree::Node, 1u, 3u, 1u>::~HazardManager() (in /home/wichtounet/dev/btrees/bin/btrees)
==9336==    by 0x418F19: avltree::AVLTree<int, 1>::~AVLTree() (AVLTree.hpp:154)
==9336==    by 0x418D9A: void testST<avltree::AVLTree<int, 1> >(std::string const&) (test.cpp:110)
==9336==    by 0x41831D: test() (test.cpp:180)
==9336==    by 0x41CFF8: main (main.cpp:19)
==9336==  Address 0x0 is not stack'd, malloc'd or (recently) free'd

在我看来,这是一个堆栈损坏的情况,但我不知道它可以来自哪里......在使用类本身时没有错误,只有当它被破坏时才会出现。

是否有可以帮助查找此错误的工具或有助于查找此类损坏何时可以发现的提示?

我正在使用GCC 4.7使用调试符号编译我的应用程序而没有优化。

提前感谢任何帮助或想法

2 个答案:

答案 0 :(得分:2)

你有可能过度索引HazardManager::Pointers会破坏列表,只有当它的析构函数试图访问无效的内存时(因为指针出现乱码)才能实现。

答案 1 :(得分:2)

切换到boost::array / std::array并使用at,您将获得out_of_range例外。