# Undefined Behaviour in ImageToImageMetricv4

**URL:** <https://discourse.itk.org/t/undefined-behaviour-in-imagetoimagemetricv4/7460>\
**Category:** Engineering\
**Created:** [March 15, 2025, 12:23am UTC](https://discourse.itk.org/t/undefined-behaviour-in-imagetoimagemetricv4/7460 "2025-03-15T00:23:38Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![spinicist](https://discourse.itk.org/user_avatar/discourse.itk.org/spinicist/32/183_2.png) [@spinicist](https://discourse.itk.org/u/spinicist)\
**Post date:** [March 15, 2025, 12:23am UTC](https://discourse.itk.org/t/undefined-behaviour-in-imagetoimagemetricv4/7460/1 "2025-03-15T00:23:38Z")

</div>

There is a note here [ITK/Modules/Registration/Metricsv4/include/itkImageToImageMetricv4.hxx at master · InsightSoftwareConsortium/ITK · GitHub](https://github.com/InsightSoftwareConsortium/ITK/blob/master/Modules/Registration/Metricsv4/include/itkImageToImageMetricv4.hxx#L120) that `ImageToImageMetricv4` does not allocate the virtual image to save memory. However, this causes undefined behaviour in `ImageRegionConstIteratorWithIndex`, because the `buffer` pointer is used in some of the iterator calculations and is set to `nullptr`. Here is a full stack trace from UBSan:

```auto
/Users/tobias/Code/riesling/build/vcpkg_installed/arm64-osx/include/ITK-5.4/itkImageRegionConstIteratorWithIndex.hxx:37:24: runtime error: applying non-zero offset 4 to null pointer
    #0 0x1052083d8 in itk::ImageRegionConstIteratorWithIndex<itk::Image<float, 3u>>::operator++() itkImageRegionConstIteratorWithIndex.hxx:37
    #1 0x1054a2848 in itk::ImageToImageMetricv4GetValueAndDerivativeThreader<itk::ThreadedImageRegionPartitioner<3u>, itk::ImageToImageMetricv4<itk::Image<float, 3u>, itk::Image<float, 3u>, itk::Image<float, 3u>, double, itk::DefaultImageToImageMetricTraitsv4<itk::Image<float, 3u>, itk::Image<float, 3u>, itk::Image<float, 3u>, double>>>::ThreadedExecution(itk::ImageRegion<3u> const&, unsigned int) itkImageToImageMetricv4GetValueAndDerivativeThreader.hxx:35
    #2 0x1055936f0 in itk::DomainThreader<itk::ThreadedImageRegionPartitioner<3u>, itk::ImageToImageMetricv4<itk::Image<float, 3u>, itk::Image<float, 3u>, itk::Image<float, 3u>, double, itk::DefaultImageToImageMetricTraitsv4<itk::Image<float, 3u>, itk::Image<float, 3u>, itk::Image<float, 3u>, double>>>::ThreaderCallback(void*) itkDomainThreader.hxx:123
    #3 0x105af7ad8 in itk::PoolMultiThreader::SingleMethodExecute()::$_0::operator()() const itkPoolMultiThreader.cxx:144
    #4 0x105aeef78 in void itk::(anonymous namespace)::ExceptionHandler::TryAndCatch<itk::PoolMultiThreader::SingleMethodExecute()::$_0>(itk::PoolMultiThreader::SingleMethodExecute()::$_0 const&) itkPoolMultiThreader.cxx:54
    #5 0x105aeec8c in itk::PoolMultiThreader::SingleMethodExecute() itkPoolMultiThreader.cxx:144
    #6 0x105ab6bb0 in itk::MultiThreaderBase::SetSingleMethodAndExecute(void* (*)(void*), void*) itkMultiThreaderBase.cxx:453
    #7 0x105592c0c in itk::DomainThreader<itk::ThreadedImageRegionPartitioner<3u>, itk::ImageToImageMetricv4<itk::Image<float, 3u>, itk::Image<float, 3u>, itk::Image<float, 3u>, double, itk::DefaultImageToImageMetricTraitsv4<itk::Image<float, 3u>, itk::Image<float, 3u>, itk::Image<float, 3u>, double>>>::StartThreadingSequence() itkDomainThreader.hxx:98
    #8 0x105591898 in itk::DomainThreader<itk::ThreadedImageRegionPartitioner<3u>, itk::ImageToImageMetricv4<itk::Image<float, 3u>, itk::Image<float, 3u>, itk::Image<float, 3u>, double, itk::DefaultImageToImageMetricTraitsv4<itk::Image<float, 3u>, itk::Image<float, 3u>, itk::Image<float, 3u>, double>>>::Execute(itk::ImageToImageMetricv4<itk::Image<float, 3u>, itk::Image<float, 3u>, itk::Image<float, 3u>, double, itk::DefaultImageToImageMetricTraitsv4<itk::Image<float, 3u>, itk::Image<float, 3u>, itk::Image<float, 3u>, double>>*, itk::ImageRegion<3u> const&) itkDomainThreader.hxx:65
    #9 0x1053492f8 in itk::ImageToImageMetricv4<itk::Image<float, 3u>, itk::Image<float, 3u>, itk::Image<float, 3u>, double, itk::DefaultImageToImageMetricTraitsv4<itk::Image<float, 3u>, itk::Image<float, 3u>, itk::Image<float, 3u>, double>>::GetValueAndDerivativeExecute() const itkImageToImageMetricv4.hxx:273
    #10 0x1053142d8 in itk::ImageToImageMetricv4<itk::Image<float, 3u>, itk::Image<float, 3u>, itk::Image<float, 3u>, double, itk::DefaultImageToImageMetricTraitsv4<itk::Image<float, 3u>, itk::Image<float, 3u>, itk::Image<float, 3u>, double>>::GetValueAndDerivative(double&, itk::Array<double>&) const itkImageToImageMetricv4.hxx:244
    #11 0x1056d0f04 in itk::GradientDescentOptimizerv4Template<double>::ResumeOptimization() itkGradientDescentOptimizerv4.hxx:99
    #12 0x1056e9908 in itk::GradientDescentOptimizerv4Template<double>::StartOptimization(bool) itkGradientDescentOptimizerv4.hxx:54
    #13 0x1056cf37c in itk::ConjugateGradientLineSearchOptimizerv4Template<double>::StartOptimization(bool) itkConjugateGradientLineSearchOptimizerv4.hxx:45
    #14 0x1058aca00 in itk::MultiStartOptimizerv4Template<double>::ResumeOptimization() itkMultiStartOptimizerv4.hxx:177
    #15 0x1058aa028 in itk::MultiStartOptimizerv4Template<double>::StartOptimization(bool) itkMultiStartOptimizerv4.hxx:154
    #16 0x105216804 in merlin::Register(itk::SmartPointer<itk::Image<float, 3u>>, itk::SmartPointer<itk::Image<float, 3u>>, itk::SmartPointer<itk::Image<float, 3u>>) merlin.cpp:346
    #17 0x104f7bdfc in main main_merlin.cpp:43
    #18 0x19bffc270 (<unknown module>)

```

While this is likely benign, it leads to a lot of line noise while trying to use UB San to find other problems. Is there any way to fix this apart from either:

1. Allocating the virtual image
2. Adding some kind of `RegionIndexIterator`?

---

<div class="post-metadata">

**Author:** ![spinicist](https://discourse.itk.org/user_avatar/discourse.itk.org/spinicist/32/183_2.png) [@spinicist](https://discourse.itk.org/u/spinicist)\
**Post date:** [March 15, 2025, 12:33am UTC](https://discourse.itk.org/t/undefined-behaviour-in-imagetoimagemetricv4/7460/2 "2025-03-15T00:33:21Z")

</div>

PS The “missing” `Allocate()` call is actually here [ITK/Modules/Numerics/Optimizersv4/include/itkObjectToObjectMetric.hxx at master · InsightSoftwareConsortium/ITK · GitHub](https://github.com/InsightSoftwareConsortium/ITK/blob/master/Modules/Numerics/Optimizersv4/include/itkObjectToObjectMetric.hxx#L234) in `itkObjectToObjectMetric.hxx`. If I add `this->m_VirtualImage->Allocate();` then the UB San messages go away, in my case the images are small so this fix would work for me.
