Skip to content

Commit dac2e95

Browse files
committed
Elem::_children should be a unique_ptr to an array of Elem*
* The Elem class is no longer manually mangaging any memory * Default the Elem destructor
1 parent e35f3fc commit dac2e95

3 files changed

Lines changed: 25 additions & 50 deletions

File tree

include/geom/elem.h

Lines changed: 20 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -110,23 +110,23 @@ class Elem : public ReferenceCountedObject<Elem>,
110110
public:
111111

112112
/**
113-
* Elems are responsible for allocating and deleting their children
114-
* during refinement, so they cannot be (default) copied or
115-
* assigned. We therefore explicitly delete these operations. Note
116-
* that because _children is a C-style array, an Elem cannot even be
117-
* safely default move-constructed (we would have to maintain a
118-
* custom move constructor that explicitly sets _children to nullptr
119-
* to do this safely).
113+
* Elems are responsible for allocating and deleting space for
114+
* storing pointers to their children during refinement, so they
115+
* cannot currently be (default) copy-constructed or copy-
116+
* assigned. We therefore explicitly delete these operations. In
117+
* addition, the DofObject base class currently has private copy
118+
* construction and assignment operators, so that prevents us from
119+
* copying Elems as well.
120120
*/
121121
Elem (Elem &&) = delete;
122122
Elem (const Elem &) = delete;
123123
Elem & operator= (const Elem &) = delete;
124124
Elem & operator= (Elem &&) = delete;
125125

126126
/**
127-
* Destructor. Frees all the memory associated with the element.
127+
* Destructor.
128128
*/
129-
virtual ~Elem();
129+
virtual ~Elem() = default;
130130

131131
/**
132132
* \returns The \p Point associated with local \p Node \p i.
@@ -2002,9 +2002,13 @@ class Elem : public ReferenceCountedObject<Elem>,
20022002

20032003
#ifdef LIBMESH_ENABLE_AMR
20042004
/**
2005-
* Pointers to this element's children.
2005+
* unique_ptr to array of this element's children.
2006+
*
2007+
* A Mesh ultimately owns the child Elems so we are not responsible
2008+
* for deleting them, but we are responsible for cleaning up the
2009+
* array allocated to hold those Elems, hence the unique_ptr.
20062010
*/
2007-
Elem ** _children;
2011+
std::unique_ptr<Elem *[]> _children;
20082012
#endif
20092013

20102014
/**
@@ -2087,19 +2091,20 @@ Elem::ConstChildRefIter : public PointerToPointerIter<const Elem>
20872091
};
20882092

20892093

2094+
20902095
inline
20912096
SimpleRange<Elem::ChildRefIter> Elem::child_ref_range()
20922097
{
20932098
libmesh_assert(_children);
2094-
return {_children, _children + this->n_children()};
2099+
return {_children.get(), _children.get() + this->n_children()};
20952100
}
20962101

20972102

20982103
inline
20992104
SimpleRange<Elem::ConstChildRefIter> Elem::child_ref_range() const
21002105
{
21012106
libmesh_assert(_children);
2102-
return {_children, _children + this->n_children()};
2107+
return {_children.get(), _children.get() + this->n_children()};
21032108
}
21042109
#endif // LIBMESH_ENABLE_AMR
21052110

@@ -2127,9 +2132,6 @@ Elem::Elem(const unsigned int nn,
21272132
Node ** nodelinkdata) :
21282133
_nodes(nodelinkdata),
21292134
_elemlinks(elemlinkdata),
2130-
#ifdef LIBMESH_ENABLE_AMR
2131-
_children(nullptr),
2132-
#endif
21332135
_sbd_id(0),
21342136
#ifdef LIBMESH_ENABLE_AMR
21352137
_rflag(Elem::DO_NOTHING),
@@ -2179,30 +2181,6 @@ Elem::Elem(const unsigned int nn,
21792181

21802182

21812183

2182-
inline
2183-
Elem::~Elem()
2184-
{
2185-
// Deleting my parent/neighbor/nodes storage isn't necessary since it's
2186-
// handled by the subclass
2187-
2188-
// if (_nodes != nullptr)
2189-
// delete [] _nodes;
2190-
// _nodes = nullptr;
2191-
2192-
// delete [] _elemlinks;
2193-
2194-
#ifdef LIBMESH_ENABLE_AMR
2195-
2196-
// Delete my children's storage
2197-
if (_children != nullptr)
2198-
delete [] _children;
2199-
_children = nullptr;
2200-
2201-
#endif
2202-
}
2203-
2204-
2205-
22062184
inline
22072185
const Point & Elem::point (const unsigned int i) const
22082186
{
@@ -2746,7 +2724,7 @@ inline
27462724
bool Elem::has_children() const
27472725
{
27482726
#ifdef LIBMESH_ENABLE_AMR
2749-
if (_children == nullptr)
2727+
if (!_children)
27502728
return false;
27512729
else
27522730
return true;
@@ -2760,7 +2738,7 @@ inline
27602738
bool Elem::has_ancestor_children() const
27612739
{
27622740
#ifdef LIBMESH_ENABLE_AMR
2763-
if (_children == nullptr)
2741+
if (!_children)
27642742
return false;
27652743
else
27662744
for (auto & c : child_ref_range())

src/geom/elem.C

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1574,9 +1574,9 @@ void Elem::add_child (Elem * elem)
15741574
{
15751575
const unsigned int nc = this->n_children();
15761576

1577-
if (_children == nullptr)
1577+
if (!_children)
15781578
{
1579-
_children = new Elem *[nc];
1579+
_children = std::make_unique<Elem *[]>(nc);
15801580

15811581
for (unsigned int c = 0; c != nc; c++)
15821582
this->set_child(c, nullptr);
@@ -1602,7 +1602,7 @@ void Elem::add_child (Elem * elem, unsigned int c)
16021602
if (!this->has_children())
16031603
{
16041604
const unsigned int nc = this->n_children();
1605-
_children = new Elem *[nc];
1605+
_children = std::make_unique<Elem *[]>(nc);
16061606

16071607
for (unsigned int i = 0; i != nc; i++)
16081608
this->set_child(i, nullptr);

src/geom/elem_refinement.C

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ void Elem::refine (MeshRefinement & mesh_refinement)
9494
// Create my children if necessary
9595
if (!_children)
9696
{
97-
_children = new Elem *[nc];
97+
_children = std::make_unique<Elem *[]>(nc);
9898

9999
unsigned int parent_p_level = this->p_level();
100100
const unsigned int nei = this->n_extra_integers();
@@ -166,8 +166,6 @@ void Elem::coarsen()
166166
libmesh_assert (!this->active());
167167

168168
// We no longer delete children until MeshRefinement::contract()
169-
// delete [] _children;
170-
// _children = nullptr;
171169

172170
unsigned int parent_p_level = 0;
173171

@@ -233,8 +231,7 @@ void Elem::contract()
233231
libmesh_assert (this->active());
234232

235233
// Active contracted elements no longer can have children
236-
delete [] _children;
237-
_children = nullptr;
234+
_children.reset(nullptr);
238235

239236
if (this->refinement_flag() == Elem::JUST_COARSENED)
240237
this->set_refinement_flag(Elem::DO_NOTHING);

0 commit comments

Comments
 (0)