samedi 3 décembre 2016

Runtime Exception thrown when std::vector destructing

First of all I want to mentioned that I am new to C/C++. I am using Visual Studio 2015 update 3 with Intel Parallel XE studio 2017(Intel C/C++ Compiler 17.0). I built my project under default visual studio debug settings.

This is my question will explain it briefly as I can. I define a class in A.h as below :

class Component
{
    public:
    Component(const std::vector<std::wstring>& testData);
    Component(Component&& para);

    Component(const Component&) = delete;
    Component& operator=(const Component&) = delete;    
};

class A
    {
    public:
        A(int testTime);
        ~A();
        void start();
        A(const A& ) = delete;
        A& operator=(const A&) = delete;
    private:
        void fabricateThings();
            const int m_testTime;

            std::vector<Component> m_tCollection = {};
        int m_numberOfVbsTests= 0;

    };

and respective A.cpp goes like this :

A::A(int time) :m_time(time)
{
    fabricateThings(); // =>(*if function call here problem arise*)

}

A::~A()
{
}

void A::start()
{
    //fabricateTests();  // =>(*if function call here problem solved*)
}
void A::fabricateTests()
{
   for (auto i = 2; i < 5; ++i)
    {
       m_tCollection.emplace_back()
       ++m_numberOfTests;
    }
    int idx = 0;

    for (const auto& e : m_tCollection) //=>(If range-based for loop removed or replaced by general for-loop problem solved)
    {
       ++idx;
    }
};

When I compiled and run my project using Intel C/C++ compiler it given me following Access Violation runtime exception and direct me to the crash zone in Standard Utility header,For your convenience I can give code snippet of it as below :(code under C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xutility.h)

{ 
// MEMBER FUNCTIONS FOR _Container_base12
inline void _Container_base12::_Orphan_all()
    {   // orphan all iterators
 #if _ITERATOR_DEBUG_LEVEL == 2
    if (_Myproxy != 0)
        {   // proxy allocated, drain it
        _Lockit _Lock(_LOCK_DEBUG);

        for (_Iterator_base12 **_Pnext = &_Myproxy->_Myfirstiter;
            *_Pnext != 0; *_Pnext = (*_Pnext)->_Mynextiter)
            (*_Pnext)->_Myproxy = 0; <= //debug pointer stuck here..
        _Myproxy->_Myfirstiter = 0;
        }
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
    }
}

The problem will be solved if I call fabricateThings() function not within constructor of its own class A,if its call under start() member function system running fine. Also If I don't use range based for loop as shown in code above within fabricateThings() function runtime exception will vanished.

If someone need to look at callstack it goes like this,started with destructor call of class A :

>   A.exe!std::_Container_base12::_Orphan_all()
A.exe!std::_Vector_alloc<std::_Vec_base_types<Component, std::allocator<Component> > >::_Orphan_all() 
A.exe!std::vector<Component, std::allocator<Component> >::_Tidy()
A.exe!std::vector<Component, std::allocator<Component> >::~vector()
A.exe!A::~A()
A.exe!main(int argc, unsigned short * * argv)

Please help me to resolved this slipknot situation,we can call member function within its constructor without unexpected behavior unless virtual function. Here I have no virtual functions. I cannot figure why Intel compiler worked this way

for (const auto& e : m_tCollection)

If removed above range-based for-loop system again works fine.I cannot understand the reason.Is this Intel Compiler bug?

Note: This bizarre situation occurred with Intel latest C/C++ compiler only. Visual C++(v.140) works fine with every situation.

Thank you.

Aucun commentaire:

Enregistrer un commentaire