简体   繁体   English

dynamic_bitset,让我的程序崩溃

[英]dynamic_bitset, crash my program

I'm new with boost.我是新手。 I have a program which uses dynamic_bitset inside a lambda function.我有一个在 lambda 函数中使用dynamic_bitset的程序。 After I try to run the program, I get this message.在我尝试运行该程序后,我收到了这条消息。 This message appears even without the function that initializes the bitset and the functions that handle it.即使没有初始化位集的bitset和处理它的函数,也会出现此消息。

Does anybody know what this message means and what might be the problem?有谁知道这条消息是什么意思,可能是什么问题?

The message:消息:

/usr/include/boost/dynamic_bitset/dynamic_bitset.hpp:616: boost::dynamic_bitset<Block, Allocator>::~dynamic_bitset() [with Block = long unsigned int, Allocator = std::allocator<long unsigned int>] : Assertion 'm_check_invariants()' failed. /usr/include/boost/dynamic_bitset/dynamic_bitset.hpp:616: boost::dynamic_bitset<Block, Allocator>::~dynamic_bitset() [with Block = long unsigned int, Allocator = std::allocator<long unsigned int>] : 断言'm_check_invariants()'失败。 Aborted中止

well the code is something like this代码是这样的
main call to this function:对该函数的主要调用:

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

the signature of getSetMask is: AtomSet getSetMask(std::function property, std::function action); getSetMask 的签名是:AtomSet getSetMask(std::function property, std::function action);

and the weirdest thing that even when i remove all the content of that function it still give me the error message最奇怪的是,即使我删除了该函数的所有内容,它仍然给我错误消息

I had a similar problem with dynamic_bitset that was solved by calling reset() on it before it got destroyed.我有一个与 dynamic_bitset 类似的问题,通过在它被破坏之前调用 reset() 解决了它。

Probably the dynamic_bitset variable that you are referencing in the lambda has gone out of scope and has already been destroyed, or something similar.您在 lambda 中引用的dynamic_bitset变量可能已经超出 scope 并且已经被破坏,或者类似的东西。 (Without the source code it's difficult to be more specific) (没有源代码很难更具体)

That can indicate that you are writing past the end of the bitset without resizing it.这可能表明您正在写入超过 bitset 的末尾而不调整它的大小。 Might want to do some bounds checking.可能想做一些边界检查。

I had that problem and it took me 3 hours to find out the problem.我遇到了这个问题,我花了 3 个小时才找出问题所在。 Here is what can happen: The operator[] in dynamic_bitset does not do bound checking.以下是可能发生的情况: dynamic_bitset中的operator[]不进行边界检查。 So, one value can be assigned outside of allowed range and this does not create any error (sanitizer/valgrind do not see anything) since dynamic_bitset is using 64 bit integers (on my computer at least) in order to store values.因此,可以在允许的范围之外分配一个值,这不会产生任何错误(sanitizer/valgrind 看不到任何东西),因为 dynamic_bitset 使用 64 位整数(至少在我的计算机上)来存储值。 So, you can get a stored integer of 32 while you allowed only 4 bits in the dynamic_bitset.因此,您可以获得 32 个存储的 integer,而在 dynamic_bitset 中只允许 4 位。 The error is triggered at a later time when m_check_invariant() is called for example when the destructor is called.该错误会在稍后调用m_check_invariant()时触发,例如在调用析构函数时。

So, the problem becomes to find this range error.所以,问题就变成了找到这个范围错误。 The solution is to edit the boost/dynamic_bitset.hpp and add print statement in the code of operator[] when an operation out of range is called.解决方法是编辑boost/dynamic_bitset.hpp并在调用超出范围的操作时在operator[]的代码中添加 print 语句。 If you cannot do that then download the boost library and install it in your home directory.如果您不能这样做,请下载 boost 库并将其安装在您的主目录中。

Read the explaination of Mathieu Dutour Sikiric.阅读 Mathieu Dutour Sikiric 的解释。 The problem is that you write outside of allowed range of the bitset via operator[] and this does not create any error because it's boost and it doesn't bother to waste compute time checking that you have right to write where you want.问题是您通过 operator[] 写入了 bitset 的允许范围之外,这不会产生任何错误,因为它是提升并且不会浪费计算时间来检查您是否有权写入您想要的位置。 It is C++ you know...你知道这是C++...

So to detect it, go to boost/dynamic_bitset/dynamic_bitset.hpp , and modify the code to impose checks every time you use operator[].因此,要检测它,请转到boost/dynamic_bitset/dynamic_bitset.hpp ,并修改代码以在每次使用 operator[] 时都进行检查。

boost/dynamic_bitset/dynamic_bitset.hpp , around line 300. 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); 
    }

This makes it easier to detect the error in your code.这使得检测代码中的错误变得更加容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM