diff --git a/math/vecops/inc/ROOT/RVec.hxx b/math/vecops/inc/ROOT/RVec.hxx index fdf9d42d011f0..89af62eb4ed7b 100644 --- a/math/vecops/inc/ROOT/RVec.hxx +++ b/math/vecops/inc/ROOT/RVec.hxx @@ -403,7 +403,11 @@ void R__CLING_PTRCHECK(off) SmallVectorTemplateBase::grow( // Always grow, even from zero. size_t NewCapacity = size_t(NextPowerOf2(this->capacity() + 2)); NewCapacity = std::min(std::max(NewCapacity, MinSize), this->SizeTypeMax()); +#ifdef _WIN32 + T *NewElts = static_cast(::operator new(NewCapacity * sizeof(T), std::nothrow)); +#else T *NewElts = static_cast(malloc(NewCapacity * sizeof(T))); +#endif R__ASSERT(NewElts != nullptr); // Move the elements over. @@ -414,8 +418,13 @@ void R__CLING_PTRCHECK(off) SmallVectorTemplateBase::grow( destroy_range(this->begin(), this->end()); // If this wasn't grown from the inline copy, deallocate the old space. +#ifdef _WIN32 + if (!this->isSmall()) + ::operator delete(this->begin()); +#else if (!this->isSmall()) free(this->begin()); +#endif } this->fBeginX = NewElts; @@ -575,8 +584,13 @@ public: { // Subclass has already destructed this vector's elements. // If this wasn't grown from the inline copy, deallocate the old space. +#ifdef _WIN32 + if (!this->isSmall() && this->Owns()) + ::operator delete(this->begin()); +#else if (!this->isSmall() && this->Owns()) free(this->begin()); +#endif } // also give up adopted memory if applicable @@ -1052,8 +1066,13 @@ RVecImpl &RVecImpl::operator=(RVecImpl &&RHS) if (!RHS.isSmall()) { if (this->Owns()) { this->destroy_range(this->begin(), this->end()); +#ifdef _WIN32 + if (!this->isSmall()) + ::operator delete(this->begin()); +#else if (!this->isSmall()) free(this->begin()); +#endif } this->fBeginX = RHS.fBeginX; this->fSize = RHS.fSize; diff --git a/math/vecops/src/RVec.cxx b/math/vecops/src/RVec.cxx index 6f54578478ecb..37de52736d8fc 100644 --- a/math/vecops/src/RVec.cxx +++ b/math/vecops/src/RVec.cxx @@ -68,6 +68,21 @@ void ROOT::Internal::VecOps::SmallVectorBase::grow_pod(void *FirstEl, size_t Min NewCapacity = std::min(std::max(NewCapacity, MinSize), SizeTypeMax()); void *NewElts; +#ifdef _WIN32 + if (fBeginX == FirstEl || !this->Owns()) { + NewElts = ::operator new(NewCapacity * TSize, std::nothrow); + R__ASSERT(NewElts != nullptr); + + // Copy the elements over. No need to run dtors on PODs. + memcpy(NewElts, this->fBeginX, size() * TSize); + } else { + // If this wasn't grown from the inline copy, grow the allocated space. + NewElts = ::operator new(NewCapacity * TSize, std::nothrow); + R__ASSERT(NewElts != nullptr); + memcpy(NewElts, this->fBeginX, size() * TSize); + ::operator delete(this->fBeginX); + } +#else if (fBeginX == FirstEl || !this->Owns()) { NewElts = malloc(NewCapacity * TSize); R__ASSERT(NewElts != nullptr); @@ -79,6 +94,7 @@ void ROOT::Internal::VecOps::SmallVectorBase::grow_pod(void *FirstEl, size_t Min NewElts = realloc(this->fBeginX, NewCapacity * TSize); R__ASSERT(NewElts != nullptr); } +#endif this->fBeginX = NewElts; this->fCapacity = NewCapacity;