Bug 678 - InternetStackHelper::SetRoutingHelper does evil things
InternetStackHelper::SetRoutingHelper does evil things
Status: RESOLVED FIXED
Product: ns-3
Classification: Unclassified
Component: helpers
ns-3-dev
All All
: P1 major
Assigned To: Tom Henderson
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2009-09-18 06:16 UTC by Gustavo J. A. M. Carneiro
Modified: 2009-10-02 01:50 UTC (History)
2 users (show)

See Also:


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

Note You need to log in before you can comment on or make changes to this bug.
Description Gustavo J. A. M. Carneiro 2009-09-18 06:16:34 UTC
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 Tom Henderson 2009-09-30 01:43:37 UTC
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 Mathieu Lacage 2009-09-30 06:58:31 UTC
(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 Tom Henderson 2009-10-01 01:49:20 UTC
Created attachment 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 Mathieu Lacage 2009-10-01 03:34:30 UTC
Comment on attachment 613 [details]
patch to fix

>+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 Tom Henderson 2009-10-02 01:50:33 UTC
(In reply to comment #4)
> (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.
> 

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