diff --git a/Modules/Core/Common/include/itkVariableLengthVector.h b/Modules/Core/Common/include/itkVariableLengthVector.h index 817281657f8..24e6a0680ba 100644 --- a/Modules/Core/Common/include/itkVariableLengthVector.h +++ b/Modules/Core/Common/include/itkVariableLengthVector.h @@ -270,10 +270,13 @@ class ITK_TEMPLATE_EXPORT VariableLengthVector void operator()(unsigned int newSize, unsigned int oldSize, TValue2 * oldBuffer, TValue2 * newBuffer) const { - itkAssertInDebugAndIgnoreInReleaseMacro(newBuffer); const size_t nb = std::min(newSize, oldSize); - itkAssertInDebugAndIgnoreInReleaseMacro(nb == 0 || (nb > 0 && oldBuffer != nullptr)); - std::copy_n(oldBuffer, nb, newBuffer); + if (nb > 0) + { + itkAssertInDebugAndIgnoreInReleaseMacro(newBuffer); + itkAssertInDebugAndIgnoreInReleaseMacro(oldBuffer); + std::copy_n(oldBuffer, nb, newBuffer); + } } }; diff --git a/Modules/Core/Common/include/itkVariableLengthVector.hxx b/Modules/Core/Common/include/itkVariableLengthVector.hxx index d790f7128a2..1931056cf9c 100644 --- a/Modules/Core/Common/include/itkVariableLengthVector.hxx +++ b/Modules/Core/Common/include/itkVariableLengthVector.hxx @@ -29,18 +29,15 @@ namespace itk template VariableLengthVector::VariableLengthVector(unsigned int length) - : m_Data(new TValue[length]) + : m_Data(length == 0 ? nullptr : new TValue[length]) , m_NumElements(length) -{ - // postcondition(s) - itkAssertInDebugAndIgnoreInReleaseMacro(m_Data != nullptr); -} +{} template VariableLengthVector::VariableLengthVector(unsigned int length, const TValue & value) : VariableLengthVector(length) { - std::fill_n(m_Data, length, value); + Fill(value); } template @@ -67,10 +64,6 @@ VariableLengthVector::VariableLengthVector(const VariableLengthVectorm_Data[0]); } - else - { - m_Data = nullptr; - } } template @@ -133,8 +126,6 @@ VariableLengthVector::VariableLengthVector( rhs) : VariableLengthVector(rhs.Size()) { - // VariableLengthVector(length) post-condition - itkAssertInDebugAndIgnoreInReleaseMacro(m_Data != nullptr); for (ElementIdentifier i = 0; i < m_NumElements; ++i) { this->m_Data[i] = static_cast(rhs[i]); @@ -191,11 +182,14 @@ VariableLengthVector::Reserve(ElementIdentifier size) } else { - m_Data = new TValue[size]; + // At this point, m_Data is null. + if (size > 0) + { + m_Data = new TValue[size]; + } m_NumElements = size; m_LetArrayManageMemory = true; } - itkAssertInDebugAndIgnoreInReleaseMacro(m_Data != nullptr); } #ifndef ITK_FUTURE_LEGACY_REMOVE @@ -274,10 +268,15 @@ VariableLengthVector::SetSize(unsigned int sz, TReallocatePolicy realloc if (reallocatePolicy(sz, m_NumElements) || !m_LetArrayManageMemory) { - auto temp = make_unique_for_overwrite(sz); // may throw - itkAssertInDebugAndIgnoreInReleaseMacro(temp); - itkAssertInDebugAndIgnoreInReleaseMacro(m_NumElements == 0 || (m_NumElements > 0 && m_Data != nullptr)); - keepValues(sz, m_NumElements, m_Data, temp.get()); + std::unique_ptr temp; + + if (sz > 0) + { + temp = make_unique_for_overwrite(sz); // may throw + itkAssertInDebugAndIgnoreInReleaseMacro(temp); + itkAssertInDebugAndIgnoreInReleaseMacro(m_NumElements == 0 || (m_NumElements > 0 && m_Data != nullptr)); + keepValues(sz, m_NumElements, m_Data, temp.get()); + } // commit changes if (m_LetArrayManageMemory) { @@ -293,10 +292,11 @@ template void VariableLengthVector::Fill(const TValue & v) { - itkAssertInDebugAndIgnoreInReleaseMacro(m_NumElements == 0 || (m_NumElements > 0 && m_Data != nullptr)); - // VC++ version of std::fill_n() expects the output iterator to be valid - // instead of expecting the range [OutIt, OutIt+n) to be valid. - std::fill(&this->m_Data[0], &this->m_Data[m_NumElements], v); + if (m_NumElements > 0) + { + itkAssertInDebugAndIgnoreInReleaseMacro(m_Data); + std::fill_n(m_Data, m_NumElements, v); + } } template