mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
FIX: incorrect DynamicList resizing logic (memory pool)
- reserve() did not set the addressable size to the current capacity before resizing, which meant that the delete[] would not have the true allocated size. Only affects memory-pool usage (#3381), which is not yet integrated ENH: remove unused DynamicList '*_unsafe()' methods - can result in a mismatch between allocated and addressed sizes, which becomes important for memory-pool usage.
This commit is contained in:
@ -106,7 +106,7 @@ void printMyString(const UList<string>& lst)
|
||||
{
|
||||
MyStrings slist2(lst);
|
||||
|
||||
Info<<slist2 << nl;
|
||||
Info<< slist2 << nl;
|
||||
}
|
||||
|
||||
|
||||
@ -204,16 +204,6 @@ int main(int argc, char *argv[])
|
||||
Info<<" " << *iter;
|
||||
}
|
||||
Info<< nl;
|
||||
|
||||
Info<< "data:" << Foam::name(ident.cdata())
|
||||
<< " size:" << ident.size() << nl;
|
||||
|
||||
|
||||
Info<< "resize_unsafe(10)" << nl;
|
||||
ident.resize_unsafe(10);
|
||||
|
||||
Info<< "data:" << Foam::name(ident.cdata())
|
||||
<< " size:" << ident.size() << nl;
|
||||
}
|
||||
|
||||
if (false)
|
||||
@ -370,7 +360,7 @@ int main(int argc, char *argv[])
|
||||
auto shrtList = ListOps::create<short>
|
||||
(
|
||||
longLabelList,
|
||||
[](const label& val){ return val; }
|
||||
[](label val){ return val; }
|
||||
);
|
||||
|
||||
printListOutputType<short>("short") << nl;
|
||||
@ -567,7 +557,7 @@ int main(int argc, char *argv[])
|
||||
auto scalars = ListOps::create<scalar>
|
||||
(
|
||||
labels,
|
||||
[](const label& val){ return scalar(1.5*val); }
|
||||
[](label val){ return scalar(1.5*val); }
|
||||
);
|
||||
Info<< "scalars: " << flatOutput(scalars) << endl;
|
||||
}
|
||||
@ -576,7 +566,7 @@ int main(int argc, char *argv[])
|
||||
auto vectors = ListOps::create<vector>
|
||||
(
|
||||
labels,
|
||||
[](const label& val){ return vector(1.2*val, -1.2*val, 0); }
|
||||
[](label val){ return vector(1.2*val, -1.2*val, 0); }
|
||||
);
|
||||
Info<< "vectors: " << flatOutput(vectors) << endl;
|
||||
}
|
||||
@ -585,7 +575,7 @@ int main(int argc, char *argv[])
|
||||
auto longs = ListOps::create<long>
|
||||
(
|
||||
labels,
|
||||
[](const label& val){ return val; }
|
||||
[](label val){ return val; }
|
||||
);
|
||||
Info<< "longs: " << flatOutput(longs) << endl;
|
||||
}
|
||||
@ -603,7 +593,7 @@ int main(int argc, char *argv[])
|
||||
(
|
||||
labelRange().cbegin(),
|
||||
labelRange(15).cend(),
|
||||
[](const label& val){ return scalar(-1.125*val); }
|
||||
[](label val){ return scalar(-1.125*val); }
|
||||
);
|
||||
Info<< "scalars: " << flatOutput(scalars) << endl;
|
||||
}
|
||||
|
||||
@ -203,7 +203,7 @@ public:
|
||||
|
||||
//- Change the value for the list capacity directly (ADVANCED, UNSAFE)
|
||||
//- Does not perform any memory management or resizing.
|
||||
void setCapacity_unsafe(const label len) noexcept { capacity_ = len; }
|
||||
void setCapacity_unsafe(label len) noexcept { capacity_ = len; }
|
||||
|
||||
//- Reserve allocation space for at least this size, allocating new
|
||||
//- space if required and \em retaining old content.
|
||||
@ -251,11 +251,6 @@ public:
|
||||
//- Shrink the allocated space to the number of elements used.
|
||||
inline void shrink_to_fit();
|
||||
|
||||
//- Shrink the internal bookkeeping of the allocated space to the
|
||||
//- number of addressed elements without affecting allocation.
|
||||
// \note when empty() it will delete any allocated memory.
|
||||
inline void shrink_unsafe();
|
||||
|
||||
|
||||
// Edit
|
||||
|
||||
|
||||
@ -68,7 +68,9 @@ inline void Foam::DynamicList<T, SizeMin>::doCapacity
|
||||
// Addressable length, possibly truncated by new capacity
|
||||
const label currLen = Foam::min(List<T>::size(), newCapacity);
|
||||
|
||||
// Consistent allocated sizing
|
||||
List<T>::setAddressableSize(capacity_);
|
||||
|
||||
if (nocopy)
|
||||
{
|
||||
List<T>::resize_nocopy(newCapacity);
|
||||
@ -95,6 +97,9 @@ inline void Foam::DynamicList<T, SizeMin>::doReserve
|
||||
// Preserve addressed size
|
||||
const label currLen = List<T>::size();
|
||||
|
||||
// Consistent allocated sizing
|
||||
List<T>::setAddressableSize(capacity_);
|
||||
|
||||
// Increase capacity (eg, doubling)
|
||||
capacity_ =
|
||||
Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_);
|
||||
@ -105,8 +110,10 @@ inline void Foam::DynamicList<T, SizeMin>::doReserve
|
||||
}
|
||||
else
|
||||
{
|
||||
List<T>::resize(capacity_);
|
||||
List<T>::resize_copy(currLen, capacity_);
|
||||
}
|
||||
|
||||
capacity_ = List<T>::size();
|
||||
List<T>::setAddressableSize(currLen);
|
||||
}
|
||||
}
|
||||
@ -271,7 +278,7 @@ inline Foam::DynamicList<T, SizeMin>::DynamicList
|
||||
List<T>(std::move(static_cast<List<T>&>(list))),
|
||||
capacity_(list.capacity())
|
||||
{
|
||||
list.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
|
||||
list.setCapacity_unsafe(0); // All contents moved
|
||||
}
|
||||
|
||||
|
||||
@ -285,7 +292,7 @@ inline Foam::DynamicList<T, SizeMin>::DynamicList
|
||||
List<T>(std::move(static_cast<List<T>&>(list))),
|
||||
capacity_(list.capacity())
|
||||
{
|
||||
list.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
|
||||
list.setCapacity_unsafe(0); // All contents moved
|
||||
}
|
||||
|
||||
|
||||
@ -361,8 +368,15 @@ inline void Foam::DynamicList<T, SizeMin>::reserve_exact
|
||||
// Preserve addressed size
|
||||
const label currLen = List<T>::size();
|
||||
|
||||
capacity_ = len;
|
||||
List<T>::resize(capacity_);
|
||||
// Consistent allocated sizing
|
||||
List<T>::setAddressableSize(capacity_);
|
||||
|
||||
// if (!nocopy)
|
||||
{
|
||||
List<T>::resize_copy(currLen, len);
|
||||
}
|
||||
|
||||
capacity_ = List<T>::size();
|
||||
List<T>::setAddressableSize(currLen);
|
||||
}
|
||||
}
|
||||
@ -449,18 +463,6 @@ inline void Foam::DynamicList<T, SizeMin>::shrink_to_fit()
|
||||
}
|
||||
|
||||
|
||||
template<class T, int SizeMin>
|
||||
inline void Foam::DynamicList<T, SizeMin>::shrink_unsafe()
|
||||
{
|
||||
if (List<T>::empty())
|
||||
{
|
||||
// Delete storage if empty
|
||||
List<T>::clear();
|
||||
}
|
||||
capacity_ = List<T>::size();
|
||||
}
|
||||
|
||||
|
||||
template<class T, int SizeMin>
|
||||
inline void
|
||||
Foam::DynamicList<T, SizeMin>::swap(List<T>& list)
|
||||
|
||||
@ -236,13 +236,6 @@ public:
|
||||
// Otherwise the contents will be uninitialized.
|
||||
inline void resize_nocopy(const label len);
|
||||
|
||||
//- Change the addressed list size directly without affecting
|
||||
//- any memory management (advanced usage).
|
||||
//
|
||||
// It is left to the caller to avoid \em unsafe lengthening beyond
|
||||
// the allocated memory region.
|
||||
inline void resize_unsafe(const label len) noexcept;
|
||||
|
||||
//- Alias for resize()
|
||||
void setSize(const label n) { this->resize(n); }
|
||||
|
||||
|
||||
@ -178,13 +178,6 @@ inline void Foam::List<T>::resize_nocopy(const label len)
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline void Foam::List<T>::resize_unsafe(const label len) noexcept
|
||||
{
|
||||
UList<T>::setAddressableSize(len);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline T& Foam::List<T>::newElmt(const label i)
|
||||
{
|
||||
|
||||
@ -112,23 +112,26 @@ public:
|
||||
|
||||
//- Change the value for the list capacity directly (ADVANCED, UNSAFE)
|
||||
//- Does not perform any memory management or resizing.
|
||||
void setCapacity_unsafe(const label len) noexcept { capacity_ = len; }
|
||||
void setCapacity_unsafe(label len) noexcept { capacity_ = len; }
|
||||
|
||||
//- Reserve allocation space for at least this size.
|
||||
// New entries are initialized to nullptr.
|
||||
inline void reserve(const label len);
|
||||
|
||||
//- Reserve allocation space for at least this size.
|
||||
//- If allocation is required, uses the specified size
|
||||
//- without any other resizing logic.
|
||||
// New entries are initialized to nullptr.
|
||||
inline void reserve_exact(const label len);
|
||||
|
||||
//- Alter the addressed list size.
|
||||
inline void resize(const label newLen);
|
||||
// New entries are initialized to nullptr.
|
||||
inline void resize(const label len);
|
||||
|
||||
//- Set the addressed list to the given size,
|
||||
//- deleting all existing entries.
|
||||
//- Afterwards the list contains all \c nullptr entries.
|
||||
inline void resize_null(const label newLen);
|
||||
inline void resize_null(const label len);
|
||||
|
||||
//- Clear the addressed list, i.e. set the size to zero.
|
||||
// Allocated size does not change
|
||||
@ -140,11 +143,6 @@ public:
|
||||
//- Shrink the allocated space to the number of elements used.
|
||||
inline void shrink_to_fit();
|
||||
|
||||
//- Shrink the internal bookkeeping of the allocated space to the
|
||||
//- number of addressed elements without affecting allocation.
|
||||
// \note when empty() it will delete any allocated memory.
|
||||
inline void shrink_unsafe();
|
||||
|
||||
//- Alias for shrink_to_fit()
|
||||
void shrink() { this->shrink_to_fit(); }
|
||||
|
||||
|
||||
@ -82,10 +82,7 @@ inline Foam::PtrDynList<T, SizeMin>::PtrDynList
|
||||
PtrList<T>(std::move(list)),
|
||||
capacity_(list.capacity())
|
||||
{
|
||||
// FUTURE:
|
||||
// list.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
|
||||
|
||||
list.clearStorage(); // capacity=0 etc.
|
||||
list.setCapacity_unsafe(0); // All contents moved
|
||||
}
|
||||
|
||||
|
||||
@ -99,10 +96,7 @@ inline Foam::PtrDynList<T, SizeMin>::PtrDynList
|
||||
PtrList<T>(std::move(list)),
|
||||
capacity_(list.capacity())
|
||||
{
|
||||
// FUTURE:
|
||||
// list.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
|
||||
|
||||
list.clearStorage(); // capacity=0 etc.
|
||||
list.setCapacity_unsafe(0); // All contents moved
|
||||
}
|
||||
|
||||
|
||||
@ -135,11 +129,17 @@ inline void Foam::PtrDynList<T, SizeMin>::reserve(const label len)
|
||||
// Preserve addressed size
|
||||
const label currLen = PtrList<T>::size();
|
||||
|
||||
// Consistent allocated sizing
|
||||
PtrList<T>::setAddressableSize(capacity_);
|
||||
|
||||
// Increase capacity (eg, doubling)
|
||||
capacity_ =
|
||||
Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_);
|
||||
|
||||
// No PtrList<T>::resize_copy(...) -> copying nullptr is cheap
|
||||
PtrList<T>::resize(capacity_);
|
||||
|
||||
capacity_ = PtrList<T>::size();
|
||||
PtrList<T>::setAddressableSize(currLen);
|
||||
}
|
||||
}
|
||||
@ -153,8 +153,13 @@ inline void Foam::PtrDynList<T, SizeMin>::reserve_exact(const label len)
|
||||
// Preserve addressed size
|
||||
const label currLen = PtrList<T>::size();
|
||||
|
||||
capacity_ = len;
|
||||
PtrList<T>::resize(capacity_);
|
||||
// Consistent allocated sizing
|
||||
PtrList<T>::setAddressableSize(capacity_);
|
||||
|
||||
// No PtrList<T>::resize_copy(...) -> copying nullptr is cheap
|
||||
PtrList<T>::resize(len);
|
||||
|
||||
capacity_ = PtrList<T>::size();
|
||||
PtrList<T>::setAddressableSize(currLen);
|
||||
}
|
||||
}
|
||||
@ -164,16 +169,12 @@ template<class T, int SizeMin>
|
||||
inline void Foam::PtrDynList<T, SizeMin>::resize(const label newLen)
|
||||
{
|
||||
auto& ptrs = this->ptrs_;
|
||||
|
||||
const label oldLen = ptrs.size();
|
||||
|
||||
if (capacity_ < newLen)
|
||||
{
|
||||
// Increase capacity (eg, doubling)
|
||||
capacity_ =
|
||||
Foam::ListPolicy::reserve_size<SizeMin, 2>(newLen, capacity_);
|
||||
|
||||
PtrList<T>::resize(capacity_);
|
||||
// Extend list
|
||||
this->reserve(newLen);
|
||||
}
|
||||
else if (newLen != oldLen)
|
||||
{
|
||||
@ -191,13 +192,16 @@ inline void Foam::PtrDynList<T, SizeMin>::resize(const label newLen)
|
||||
|
||||
|
||||
template<class T, int SizeMin>
|
||||
inline void Foam::PtrDynList<T, SizeMin>::resize_null(const label newLen)
|
||||
inline void Foam::PtrDynList<T, SizeMin>::resize_null(const label len)
|
||||
{
|
||||
if (capacity_ < newLen)
|
||||
if (capacity_ < len)
|
||||
{
|
||||
// Consistent allocated sizing
|
||||
PtrList<T>::setAddressableSize(capacity_);
|
||||
|
||||
// Increase capacity (eg, doubling)
|
||||
capacity_ =
|
||||
Foam::ListPolicy::reserve_size<SizeMin, 2>(newLen, capacity_);
|
||||
Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_);
|
||||
|
||||
PtrList<T>::resize_null(capacity_);
|
||||
}
|
||||
@ -207,7 +211,7 @@ inline void Foam::PtrDynList<T, SizeMin>::resize_null(const label newLen)
|
||||
}
|
||||
|
||||
// Adjust addressed size
|
||||
PtrList<T>::setAddressableSize(newLen);
|
||||
PtrList<T>::setAddressableSize(len);
|
||||
}
|
||||
|
||||
|
||||
@ -240,18 +244,6 @@ inline void Foam::PtrDynList<T, SizeMin>::shrink_to_fit()
|
||||
}
|
||||
|
||||
|
||||
template<class T, int SizeMin>
|
||||
inline void Foam::PtrDynList<T, SizeMin>::shrink_unsafe()
|
||||
{
|
||||
if (PtrList<T>::empty())
|
||||
{
|
||||
// Delete empty list
|
||||
PtrList<T>::clear();
|
||||
}
|
||||
capacity_ = PtrList<T>::size();
|
||||
}
|
||||
|
||||
|
||||
template<class T, int SizeMin>
|
||||
inline Foam::label Foam::PtrDynList<T, SizeMin>::squeezeNull()
|
||||
{
|
||||
|
||||
@ -217,7 +217,7 @@ public:
|
||||
|
||||
//- Change the value for the list capacity directly (ADVANCED, UNSAFE)
|
||||
//- Does not perform any memory management or resizing.
|
||||
void setCapacity_unsafe(const label len) noexcept { capacity_ = len; }
|
||||
void setCapacity_unsafe(label len) noexcept { capacity_ = len; }
|
||||
|
||||
//- Reserve allocation space for at least this size, allocating new
|
||||
//- space if required and \em retaining old content.
|
||||
@ -265,11 +265,6 @@ public:
|
||||
//- Shrink the allocated space to the number of elements used.
|
||||
inline void shrink_to_fit();
|
||||
|
||||
//- Shrink the internal bookkeeping of the allocated space to the
|
||||
//- number of addressed elements without affecting allocation.
|
||||
// \note when empty() it will delete any allocated memory.
|
||||
inline void shrink_unsafe();
|
||||
|
||||
|
||||
// Edit
|
||||
|
||||
|
||||
@ -66,7 +66,9 @@ inline void Foam::DynamicField<T, SizeMin>::doCapacity
|
||||
// Addressable length, possibly truncated by new capacity
|
||||
const label currLen = Foam::min(List<T>::size(), newCapacity);
|
||||
|
||||
// Consistent allocated sizing
|
||||
List<T>::setAddressableSize(capacity_);
|
||||
|
||||
if (nocopy)
|
||||
{
|
||||
List<T>::resize_nocopy(newCapacity);
|
||||
@ -93,6 +95,9 @@ inline void Foam::DynamicField<T, SizeMin>::doReserve
|
||||
// Preserve addressed size
|
||||
const label currLen = List<T>::size();
|
||||
|
||||
// Consistent allocated sizing
|
||||
List<T>::setAddressableSize(capacity_);
|
||||
|
||||
// Increase capacity (eg, doubling)
|
||||
capacity_ =
|
||||
Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_);
|
||||
@ -103,8 +108,10 @@ inline void Foam::DynamicField<T, SizeMin>::doReserve
|
||||
}
|
||||
else
|
||||
{
|
||||
List<T>::resize(capacity_);
|
||||
List<T>::resize_copy(currLen, capacity_);
|
||||
}
|
||||
|
||||
capacity_ = List<T>::size();
|
||||
List<T>::setAddressableSize(currLen);
|
||||
}
|
||||
}
|
||||
@ -246,7 +253,7 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField
|
||||
Field<T>(std::move(static_cast<List<T>&>(content))),
|
||||
capacity_(content.capacity())
|
||||
{
|
||||
content.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
|
||||
content.setCapacity_unsafe(0); // All contents moved
|
||||
}
|
||||
|
||||
|
||||
@ -259,7 +266,7 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField
|
||||
Field<T>(std::move(static_cast<List<T>&>(content))),
|
||||
capacity_(content.capacity())
|
||||
{
|
||||
content.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
|
||||
content.setCapacity_unsafe(0); // All contents moved
|
||||
}
|
||||
|
||||
|
||||
@ -273,7 +280,7 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField
|
||||
Field<T>(std::move(static_cast<List<T>&>(content))),
|
||||
capacity_(content.capacity())
|
||||
{
|
||||
content.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
|
||||
content.setCapacity_unsafe(0); // All contents moved
|
||||
}
|
||||
|
||||
|
||||
@ -292,7 +299,7 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField
|
||||
{
|
||||
Field<T>::transfer(static_cast<List<T>&>(content));
|
||||
capacity_ = content.capacity();
|
||||
content.setCapacity_unsafe(0);
|
||||
content.setCapacity_unsafe(0); // All contents moved
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -317,7 +324,7 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField
|
||||
{
|
||||
Field<T>::transfer(static_cast<List<T>&>(content));
|
||||
capacity_ = content.capacity();
|
||||
content.setCapacity_unsafe(0);
|
||||
content.setCapacity_unsafe(0); // All contents moved
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -462,8 +469,15 @@ inline void Foam::DynamicField<T, SizeMin>::reserve_exact
|
||||
// Preserve addressed size
|
||||
const label currLen = List<T>::size();
|
||||
|
||||
capacity_ = len;
|
||||
List<T>::resize(capacity_);
|
||||
// Consistent allocated sizing
|
||||
List<T>::setAddressableSize(capacity_);
|
||||
|
||||
// if (!nocopy)
|
||||
{
|
||||
List<T>::resize_copy(currLen, len);
|
||||
}
|
||||
|
||||
capacity_ = List<T>::size();
|
||||
List<T>::setAddressableSize(currLen);
|
||||
}
|
||||
}
|
||||
@ -551,18 +565,6 @@ inline void Foam::DynamicField<T, SizeMin>::shrink_to_fit()
|
||||
}
|
||||
|
||||
|
||||
template<class T, int SizeMin>
|
||||
inline void Foam::DynamicField<T, SizeMin>::shrink_unsafe()
|
||||
{
|
||||
if (List<T>::empty())
|
||||
{
|
||||
// Delete storage if empty
|
||||
List<T>::clear();
|
||||
}
|
||||
capacity_ = List<T>::size();
|
||||
}
|
||||
|
||||
|
||||
template<class T, int SizeMin>
|
||||
inline void
|
||||
Foam::DynamicField<T, SizeMin>::swap(List<T>& list)
|
||||
|
||||
Reference in New Issue
Block a user