From b98992939a079af1eeb9fb5aeb6dd5e5c546daf1 Mon Sep 17 00:00:00 2001
From: Hans Johnson <hans-johnson@uiowa.edu>
Date: Fri, 23 Oct 2015 13:00:30 -0500
Subject: [PATCH] BUG: Make valid calling with m_NumElements == 0

In this test call, m_Data is nullptr, and m_NumElements is 0, so
clearly,&m_Data[0] is not a useful pointer, and with 0 elements, there
is nothing to fill.

This implements checking for zero element objects.

Change-Id: I6b9ba9d6ddf05450485a88ffbff4f14568205f26
---

diff --git a/Modules/Core/Common/include/itkVariableLengthVector.hxx b/Modules/Core/Common/include/itkVariableLengthVector.hxx
index 796a509..35abed5 100644
--- a/Modules/Core/Common/include/itkVariableLengthVector.hxx
+++ b/Modules/Core/Common/include/itkVariableLengthVector.hxx
@@ -73,7 +73,11 @@
   m_NumElements = v.Size();
   m_Data = this->AllocateElements(m_NumElements);
   m_LetArrayManageMemory = true;
-  std::copy(&v.m_Data[0], &v.m_Data[m_NumElements], &this->m_Data[0]);
+  if( this->m_NumElements != 0 )
+    {
+    TValue * const startingArrayMemory = &this->m_Data[0];
+    std::copy(&v.m_Data[0], &v.m_Data[m_NumElements], startingArrayMemory);
+    }
 }
 
 #if defined(ITK_HAS_CXX11_RVREF)
@@ -288,7 +292,11 @@
 void VariableLengthVector< TValue >
 ::Fill(TValue const & v) ITK_NOEXCEPT
 {
-  std::fill_n(&this->m_Data[0], m_NumElements, v);
+  if( this->m_NumElements != 0 )
+    {
+    TValue * const startingArrayMemory = &this->m_Data[0];
+    std::fill_n(startingArrayMemory, m_NumElements, v);
+    }
 }
 
 /** Copy-Assignment operator */
@@ -303,7 +311,11 @@
   // - the test becomes a pessimization as we never write "v = v;".
   ElementIdentifier const N = v.Size();
   this->SetSize( N, DontShrinkToFit(), DumpOldValues() );
-  std::copy(&v.m_Data[0], &v.m_Data[N], &this->m_Data[0]);
+  if( this->m_NumElements != 0 )
+    {
+    TValue * const startingArrayMemory = &this->m_Data[0];
+    std::copy(&v.m_Data[0], &v.m_Data[N], startingArrayMemory);
+    }
 
   return *this;
 }
@@ -318,8 +330,11 @@
   itkAssertInDebugAndIgnoreInReleaseMacro(this->m_LetArrayManageMemory);
   ElementIdentifier const N = v.Size();
   itkAssertInDebugAndIgnoreInReleaseMacro(N == this->Size());
-  std::copy(&v.m_Data[0], &v.m_Data[N], &this->m_Data[0]);
-
+  if( this->m_NumElements != 0 )
+    {
+    TValue * const startingArrayMemory = &this->m_Data[0];
+    std::copy(&v.m_Data[0], &v.m_Data[N], startingArrayMemory);
+    }
   return *this;
 }
 
