c++ dynamic_bitset,使我的程序崩溃

tjvv9vkg  于 2022-12-20  发布在  其他
关注(0)|答案(5)|浏览(215)

我是boost的新手,我有一个在lambda函数中使用dynamic_bitset的程序,当我尝试运行这个程序时,我得到了这个消息,这个消息甚至在没有初始化bitset的函数和处理它的函数的情况下也会出现。
有人知道这条信息是什么意思吗?可能是什么问题?
该消息:
/usr/包含/增强/动态位集/动态位集.hpp:616:boost::dynamic_bitset<Block, Allocator>::~dynamic_bitset() [with Block = long unsigned int, Allocator = std::allocator<long unsigned int>]:Assert'm_check_invariants()'失败。已中止
代码是这样的
此函数的主调用:

int Molecule::initSimilarity(int depth){
    cout << "_size is: " << _size << "\t depth is: " << depth << endl; //TODO delete
    AtomSet viewing(_size);
    int m = 0;
    {
        // break into initial groups by symbol and valancy
        for(int i=0 ; i<_size ; i++)
        {
            if(viewing[i]) continue;
            AtomSet mask = getSetMask( //AtomSet is typedef for dynamic_bitset
                [&](const Atom& b)->bool
                {
                    return (!viewing[b._index] && b._valence == _atoms[i]->_valence && strcmp(b._symbol, _atoms[i]->_symbol) == 0);
                },
                [&](Atom &b)
                {
                    b._class = m; //set the equivalence class of atom 'b' to 'm'
                }
            );
            m++;
            viewing |= mask; //viewing now contains a set of atoms and for each atom it's equivalence class
        }
        cout << "number of equivalence class: " << m << endl; //TODO DELETE!
    }    
    for (int j = 0; j < depth ; j++){
        AtomSet viewed(_size);

        int before = m;
        // iteratively refine the breakdown into groups
        for (int i = 0 ; i < _size ; i++)   //for any atom A
        {
            if (viewed[i]) continue;
            viewed.flip(i);
            AtomSet mask = getSetMask(//put all atoms which are equivalnt but not similar to A in
                //their own equivalence class
                [&](const Atom& b)->bool
                {
                    if (viewed[b._index])
                        return false; //if b is in viewed return false;
                    if (_atoms[i]->_class == b._class) //if in the same class add b to viewed
                    {
                        viewed.flip(b._index);
                        bool similar = !isSimilar(*_atoms[i],b);
                        return similar;
                    }
                    return false;
                },
                [&m](Atom& b)
                {
                    b._class = m;
                }
            );
            if (!mask.none()) m++;
        }
        if (before == m){
            std::cout << "Finished early after just " << j << " iterations" << std::endl;
            return m;
        }
    }
    return m;
}

getSetMask签名为:AtomSet getSetMask(标准::函数属性,标准::函数动作);
最奇怪的是,即使我删除了该函数的所有内容,它仍然给予我错误消息

93ze6v8z

93ze6v8z1#

可能你在lambda中引用的dynamic_bitset变量已经超出了作用域,并且已经被销毁了,或者类似的情况(没有源代码,很难更具体地说明)。

f1tvaqid

f1tvaqid2#

我遇到了那个问题,我花了3个小时才找到问题所在。以下是可能发生的情况:dynamic_bitset中的运算符[]不执行边界检查。因此,可以在允许的范围之外分配一个值,这不会产生任何错误(sanitizer/valgrind看不到任何内容),因为dynamic_bitset使用的是64位整数(至少在我的电脑上)以便存储值。所以,您可以获取存储的整数32,而dynamic_bitset中只允许4位。该错误将在以后m_check_invariant()在调用析构函数时被调用。
因此,问题是找到这个范围错误。解决方案是编辑
boost/dynamic_bitset.hpp
,并在调用超出范围的操作时在**operator[]**的代码中添加print语句。如果无法做到这一点,请下载boost库并将其安装到您的主目录中。

tzxcd3kk

tzxcd3kk3#

我在dynamic_bitset中遇到过类似的问题,通过在它被销毁之前调用reset()解决了这个问题。

yruzcnhs

yruzcnhs4#

这可能表示您正在写入超过位集的结尾而没有调整其大小。可能需要做一些边界检查。

pftdvrlh

pftdvrlh5#

阅读Mathieu Dutour Sikiric的解释。问题是你通过operator[]写超出位集允许范围的内容,这不会产生任何错误,因为它是boost,它不需要浪费计算时间来检查你是否有权写你想写的地方。这是C++,你知道...
因此,要检测它,请转到boost/dynamic_bitset/dynamic_bitset.hpp,并修改代码,以便在每次使用operator[]时强制执行检查。
boost/dynamic_bitset/dynamic_bitset.hpp,在300线附近。

reference operator[](size_type pos) {
        assert(m_check_invariants());
        return reference(m_bits[block_index(pos)], bit_index(pos));
    }
    bool operator[](size_type pos) const { 
        assert(m_check_invariants());
        return test(pos); 
    }

这样可以更容易地检测代码中的错误。

相关问题