https://svn.lrde.epita.fr/svn/oln/trunk/milena
I need to check whether we could get rid of all those dynamic
allocations. I think so, but I'm unsure.
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Address memory leaks in graphs.
* mln/util/internal/graph_base.hh
(mln::util::internal::graph_base<N, E>::self_t): New typedef.
(mln::util::internal::graph_base<N, E>::nodes_t)
(mln::util::internal::graph_base<N, E>::edges_t)
(mln::util::internal::graph_base<N, E>::edges_set_t):
Help the compiler find types util::node and util::egde.
(mln::util::internal::graph_base<N, E>::graph_base(const self_t&)):
New copy ctor.
(mln::util::internal::graph_base<N, E>::operator=(const self_t&)):
New assignment operator.
(mln::util::internal::graph_base<N, E>::~graph_base):
Remove dynamically allocated data.
graph_base.hh | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 69 insertions(+), 11 deletions(-)
Index: mln/util/internal/graph_base.hh
--- mln/util/internal/graph_base.hh (revision 1881)
+++ mln/util/internal/graph_base.hh (working copy)
@@ -151,22 +151,26 @@
template<typename N, typename E>
class graph_base
{
+ typedef graph_base<N, E> self_t;
+
public:
/* FIXME: Do we really want handle nodes and edges through
pointers? In my (Roland) opinion, this is just a drawback,
here. */
/// The type of the set of nodes.
- typedef std::vector< node<N>* > nodes_t;
+ typedef std::vector< util::node<N>* > nodes_t;
/// The type of the set of edges.
- typedef std::vector< edge<E>* > edges_t;
+ typedef std::vector< util::edge<E>* > edges_t;
/// A set to test the presence of a given edge.
- typedef std::set< edge<E>* > edges_set_t;
-
+ typedef std::set< util::edge<E>* > edges_set_t;
- /// Constructor.
+ /// Construction, assignments and destruction.
+ /// \{
graph_base();
- /// Destructor.
+ graph_base(const self_t& rhs);
+ self_t& operator=(const self_t& rhs);
~graph_base();
+ /// \}
/// Return the node whose id is \a n.
/// \{
@@ -243,9 +247,9 @@
namespace internal
{
- /*----------------.
- | Ctor and dtor. |
- `----------------*/
+ /*--------------------------------------------.
+ | Construction, assignments and destruction. |
+ `--------------------------------------------*/
template<typename N, typename E>
inline
@@ -256,10 +260,64 @@
template<typename N, typename E>
inline
+ graph_base<N, E>::graph_base(const graph_base<N, E>& rhs)
+ : nodes_(), edges_(), edges_set_()
+ {
+ nodes_.reserve(rhs.nodes_.size());
+ edges_.reserve(rhs.edges_.size());
+ for (typename nodes_t::const_iterator n = rhs.nodes_.begin();
+ n != rhs.nodes_.end(); ++n)
+ nodes_.push_back(new util::node<N>(**n));
+ for (typename edges_t::const_iterator e = rhs.edges_.begin();
+ e != rhs.edges_.end(); ++e)
+ edges_.push_back(new util::edge<E>(**e));
+ std::copy(edges_.begin(), edges_.end(),
+ std::insert_iterator<edges_set_t>(edges_set_,
+ edges_set_.begin()));
+ }
+
+ template<typename N, typename E>
+ inline
+ graph_base<N, E>&
+ graph_base<N, E>::operator=(const graph_base<N, E>& rhs)
+ {
+ if (this != &rhs)
+ {
+ /// Free previous nodes and edges.
+ for (typename nodes_t::iterator n = nodes_.begin();
+ n != nodes_.end(); ++n)
+ delete *n;
+ for (typename edges_t::iterator e = edges_.begin();
+ e != edges_.end(); ++e)
+ delete *e;
+ edges_set_.clear();
+ /// Assign values from RHS.
+ nodes_.reserve(rhs.nodes_.size());
+ edges_.reserve(rhs.edges_.size());
+ for (typename nodes_t::const_iterator n = rhs.nodes_.begin();
+ n != rhs.nodes_.end(); ++n)
+ nodes_.push_back(new util::node<N>(**n));
+ for (typename edges_t::const_iterator e = rhs.edges_.begin();
+ e != rhs.edges_.end(); ++e)
+ edges_.push_back(new util::edge<E>(**e));
+ std::copy(edges_.begin(), edges_.end(),
+ std::insert_iterator<edges_set_t>(edges_set_,
+ edges_set_.begin()));
+ }
+ return *this;
+ }
+
+ template<typename N, typename E>
+ inline
graph_base<N, E>::~graph_base()
{
- // FIXME: Delete data dynamically allocated in nodes_ and
- // edges_.
+ for (typename nodes_t::iterator n = nodes_.begin(); n != nodes_.end();
+ ++n)
+ delete *n;
+ for (typename edges_t::iterator e = edges_.begin(); e != edges_.end();
+ ++e)
+ delete *e;
+ edges_set_.clear();
}
/*------------.