C++11 VariableLengthVector with move

I am just tracking down a segmentation fault I am encountering wth the ITKTextureFeature modules instantiated with VectorImages.

I am tracking it down to using move operations of the VariableLengthVector:

It appears related to previously a deep copy was done, but now the move assignment is keeping the data to memory which has been released for a “GetPixel” type operation… Still looking deeper…

Maybe here?:

And the constructor here, defaults to m_LetArrayManageMemory(false)

So I think it could be solved if the move constructor does not modify v.m_LetArrayManageMemory?

so:

template< typename TValue >
VariableLengthVector< TValue >
::VariableLengthVector(Self && v) noexcept
: m_LetArrayManageMemory(v.m_LetArrayManageMemory)
, m_Data                (v.m_Data)
, m_NumElements         (v.m_NumElements)
{
// Do not modify v.m_LetArrayManageMemory
v.m_Data                 = nullptr;
v.m_NumElements          = 0;
}

Not 100% sure though.

Or even, set it to false directly?

I found the solution to my problem and made a pull request here:
https://github.com/InsightSoftwareConsortium/ITKTextureFeatures/pull/53

The assignment operator very nicely separate out the cases:

There may be some things suspicious with the move constructor. But I think it’s OK for the rvalue reference to be set to manage it’s own memory and a nullptr. The problem I see is what is the intent of the following code:

VariableLengthVectorType v = vector_image->GetPixelIndex(idx);

The constructor vs the assignment operator have different behavior. This is actually a call to the move constructor, where v with reference the image buffer. But if it was a call to the assignment operator, the vector v, would not be a proxy, and would have it’s own memory, so it would be a deep copy. This may result in un intended aliasing.

This is a complicated situation that needs a little more examination and verification.

2 Likes