Double delete in initializer_list vs 2013

后端 未结 1 1773
野的像风
野的像风 2020-11-29 11:59

Today in run into a memory problem in my project, with a class using c++ 11 initializer_list. The system signals a memory problem: \"Expression _BLOCK_TYPE_IS_VALID(pHead->n

相关标签:
1条回答
  • 2020-11-29 13:01

    The initializer_list behavior is buggy. In its destructor it calls a vector delete (a delete[]) of the entire range and then deletes the first entry in the array again. This behavior is not part of the initializer_list class and looks like a compiler bug. initializer_list doesn't have a destructor and doesn't allocate the array used for the list. It just looks like a wrapper for a C array.

    As for using the extra copy you see, it's caused by the vector resizing from during its initialization. Here's your flow:

    Init 00B7FAE8       // construct "foo"
    Init 00B7FBE8       // construct "bar"
    Copy 00E108A0       // copy "foo" to vector (capacity=1)
    Copy 00E10AE8 (?????) // copy the above object to the resized vector (capacity = 2)
    Deleting b 00E108A0   // delete the smaller vector buffer
    Copy 00E10BE8         // copy "bar" from initialization_list to vector
    
    Deleting b 00B7FBE8   // delete initialization_list in reverse order. this is "bar"
    Deleting b 00B7FAE8   // last to delete. this is "foo"
    
    Deleting b 00B7FAE8  (bug)
    
    // later C::bs is destroyed
    

    What you can see here is the initializing a vector via push_back is quite slow due to copying. This would be happen even if you've used the more elegant way:

    C(initializer_list<B> bb) : bs(bb) {}
    

    A faster (no extra copies) method is:

    C(initializer_list<B> bb) {
        bs.reserve(bb.size());
        bs.insert(bs.end(), bb.begin(), bb.end());
    }
    
    0 讨论(0)
提交回复
热议问题