I got an Assertion failed error while resizing a vector in a plug-in algorithm.
In order to isolate the problem I created a simple model class in Navigator.h file as shown below:
//========================= begin code =======================
class CStateStats
{
public:
DOUBLE m_dblSum;
DOUBLE m_dblSqrSum;
public:
CStateStats()
{
m_dblSum = 0.0;
m_dblSqrSum = 0.0;
}
};
class CAttStats : public DMHALLOC
{
public:
dmh_vector<CStateStats> vstatestats;
public:
CAttStats() : vstatestats (*this)
{
}
};
//========================= end code =======================
The access to DMHALLOC is provided in that class and in Navigator class as shown below:
//========================= begin code =======================
class ATL_NO_VTABLE NAVIGATOR :
public DMHALLOC,
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<NAVIGATOR, &CLSID_NAVIGATOR>,
public ISupportErrorInfo,
public IDMAlgorithmNavigation
{
public:
NAVIGATOR() : _viAttributeOutput(*this), _vCAttStats(*this)
//========================= end code =======================
I succeded making room for _vCAttStats vector, but when I tried providing room for the vectors of the vector I got an Assertion failed error (file dmhallocator.h Line:56 Expression assert(_dmhalloc._spidmmemoryallocator != NULL)). Please, see the code below, included in NAVIGATOR::GetNodeArrayProperty function:
//========================= begin code =======================
_vCAttStats.resize (2); // <<<<< succeeded here!
// make space for the states
_vCAttStats[0].vstatestats.resize(ulStates); // <<<<<<< assertion failed here!
//========================= end code =======================
I tried using a vector-of-vector approach and I also succeeded.
But I have to use that kind of structure: a vector of class with a vector inside.
I think I must provide a similar approach of vector-of-vector existing in DmhVector.h but I don't know how to do it.
I would apreciate any help.
hello,Claudio
It looks like:
- the original DMHALLOC (containing the allocator pointer), NAVIGATOR is passed properly to the vector of CAttStats, _vCAttStats and used correctly in resizing it
- during resize, STL calls the default constructor for CAttStats , which does not take any argument. Consequently, the CAttStats DMHALLOC instance does not contain an allocator pointer
- _vCAttStats[0].vstatestats.resize(ulStates); attempts to resize the vstatestats vector, which does not have a properly initialized DMHALLOC , hence the assertion that fails
To confirm my hypothesis in your code, try to use _vCAttStats[0].vstatestats.get_allocator() right before calling resize. It is likely NULL or uninitialized (well, not the actual object which is a reference, but the IDMMemoryAllocator pointer it contains).
The simplest and most reliable solution is:
- do not derive CAttStats from DMHALLOC
- use, instead, an IDMMemoryAllocator member inside the CAttStats
- explicitly set that member to the current allocator before using vstatestats
- use IDMMemoryAllocator->Alloc( n*sizeof(CStateStats) ) to get a C-style buffer of state stats which can be freed in the destructor of CAttStats with IDMMemoryAllocator->Free
Hope this helps
|||Hi Bogdan,
Thanks for you help.
I suceeded using your suggestions.
The drawbacks of this approach are that I have to explicitly initialize vstatestats because the class constructor is not called anymore when I provide room for the buffer and I don't have anymore the vector facilities. Am I correct?
No comments:
Post a Comment