From 2cd2732fed2c1ba3d3d7b12eb471c12957c2ed17 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Tue, 9 Oct 2018 08:27:50 +0200 Subject: [PATCH] ENH: avoid change when setting UPtrList twice (issue #1035) UPtrList::set(const label i, T* ptr); No-op if the new pointer value is identical to the current content. This avoid memory management issues. --- applications/test/PtrList/Test-PtrList.C | 11 +++++++++++ src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H | 1 + src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.H | 2 +- src/OpenFOAM/containers/PtrLists/UPtrList/UPtrListI.H | 4 ++++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/applications/test/PtrList/Test-PtrList.C b/applications/test/PtrList/Test-PtrList.C index e76ee21e09..70e8ce184c 100644 --- a/applications/test/PtrList/Test-PtrList.C +++ b/applications/test/PtrList/Test-PtrList.C @@ -328,6 +328,17 @@ int main(int argc, char *argv[]) <<"addresses:" << nl; printAddr(Info, list1); printAddr(Info, list1a); + Info<<"values:" << nl; + print(Info, list1a); + + // This should not cause problems (ie, no deletion) + { + auto* ptr = &(list1a.first()); + list1a.set(0, ptr); + Info<<"values:" << nl; + print(Info, list1a); + } + PtrList list1b(list1a, true); diff --git a/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H b/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H index 291fc65ff3..d1296de3f2 100644 --- a/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H +++ b/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H @@ -154,6 +154,7 @@ public: inline bool set(const label i) const; //- Set element to given pointer and return old element (can be null) + // No-op if the new pointer value is identical to the current content. inline autoPtr set(label i, T* ptr); //- Set element to given autoPtr and return old element diff --git a/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.H b/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.H index f778c850f9..99664df337 100644 --- a/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.H +++ b/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.H @@ -182,7 +182,7 @@ public: //- Set element to specified pointer and return the old list element, //- which can be a nullptr. - // No checks on new element + // No-op if the new pointer value is identical to the current content. inline T* set(const label i, T* ptr); //- Reorder elements. Reordering must be unique (ie, shuffle). diff --git a/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrListI.H b/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrListI.H index d416564a3b..6045c8ab3b 100644 --- a/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrListI.H +++ b/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrListI.H @@ -180,6 +180,10 @@ template inline T* Foam::UPtrList::set(const label i, T* ptr) { T* old = ptrs_[i]; + if (old == ptr) + { + return nullptr; // Content did not change + } ptrs_[i] = ptr; return old; }