Bug 678 - InternetStackHelper::SetRoutingHelper does evil things
: InternetStackHelper::SetRoutingHelper does evil things
Status: RESOLVED FIXED
: ns-3
helpers
: ns-3-dev
: All All
: P1 major
Assigned To:
:
:
:
:
  Show dependency treegraph
 
Reported: 2009-09-18 06:16 EDT by
Modified: 2009-10-02 01:50 EDT (History)


Attachments
patch to fix (16.54 KB, patch)
2009-10-01 01:49 EDT, Tom Henderson
Details | Diff


Note

You need to log in before you can comment on or make changes to this bug.


Description From 2009-09-18 06:16:34 EDT
void 
InternetStackHelper::SetRoutingHelper (const Ipv4RoutingHelper &routing)
{
  m_routing = &routing;
}

It takes the address of an existing object, instead of copying it.  It means I
cannot do this:

InternetStackHelper internet;
internet.SetRoutingHelper (OlsrHelper())

The above code will crash (due to a pointer to a temporary stack allocated
object), and an inexperienced programmer will have no idea why.
------- Comment #1 From 2009-09-30 01:43:37 EDT -------
The basic problem here is that we seem to need a virtual constructor for a
stack-allocated helper.  Traditional ns-3 virtual constructor using CopyObject
do not seem to apply if we want to keep these non-Ptr based.

If we want to keep the API to be 
  InternetStackHelper::SetRoutingHelper (const Ipv4RoutingHelper &routing);

and allow the user to pass anonymous temporary objects, then, we could have a
solution along these lines:

class Ipv4RoutingHelper
{
public:
  virtual Ipv4RoutingHelper* Copy (void) const = 0;
}

class Ipv4ListRoutingHelper : public Ipv4RoutingHelper
{
public:
  Ipv4ListRoutingHelper ();
  Ipv4ListRoutingHelper (const Ipv4ListRoutingHelper &);
  Ipv4ListRoutingHelper &operator = (const Ipv4ListRoutingHelper &o);
  Ipv4ListRoutingHelper* Copy (void) const 
    { return new Ipv4ListRoutingHelper (*this); }


The problem with this is that it deviates from our memory management convention
of not passing memory ownership across APIs using raw pointers.  

Am not seeing another clean alternative at the moment-- other ideas?
------- Comment #2 From 2009-09-30 06:58:31 EDT -------
(In reply to comment #1)

> class Ipv4ListRoutingHelper : public Ipv4RoutingHelper
> {
> public:
>   Ipv4ListRoutingHelper ();
>   Ipv4ListRoutingHelper (const Ipv4ListRoutingHelper &);
>   Ipv4ListRoutingHelper &operator = (const Ipv4ListRoutingHelper &o);
>   Ipv4ListRoutingHelper* Copy (void) const 
>     { return new Ipv4ListRoutingHelper (*this); }

> Am not seeing another clean alternative at the moment-- other ideas?

This is exactly what I expected to do here.
------- Comment #3 From 2009-10-01 01:49:20 EDT -------
Created an attachment (id=613) [details]
patch to fix

This patch fixes this bug along the lines of the previous comment, for both
IPv4 and IPv6.  ./waf --valgrind --regression is clean.
------- Comment #4 From 2009-10-01 03:34:30 EDT -------
(From update of attachment 613 [details])
>+Ipv4GlobalRoutingHelper &
>+Ipv4GlobalRoutingHelper::operator = (const Ipv4GlobalRoutingHelper &o)
>+{
>+  return *this;
>+}

Do you really need this ? Can't you just declare this operator private to
disable it ?

Anyway, the patch looks good to me: +1.
------- Comment #5 From 2009-10-02 01:50:33 EDT -------
(In reply to comment #4)
> (From update of attachment 613 [details] [details])
> >+Ipv4GlobalRoutingHelper &
> >+Ipv4GlobalRoutingHelper::operator = (const Ipv4GlobalRoutingHelper &o)
> >+{
> >+  return *this;
> >+}
> 
> Do you really need this ? Can't you just declare this operator private to
> disable it ?
> 
> Anyway, the patch looks good to me: +1.
> 

I don't need them, so I privatized them all.  changeset a63513286aa0.  Thanks
for reviewing it.