Help! I Have a Memory Leak

Recently i had a project which had some of the worst memory leaks in C++ i’ve ever had to deal with. It had just about every memory leak problem you could think of, all of which could have been solved with a little bit of planning.

Using tools such as Valgrind or Instruments surely helps, but they can only help you so much.

So if you have a nightmarish C++ project with memory leaks, heres a few ways in which you can solve them.

Stage 1: Forgetfulness

We start off with a simple case: when you make an object but never delete it. e.g.:

  Object *foo = new Object(); // foo never deleted

Which can be solved by:

  delete foo; // <<< delete the object

Stage 2: Garbage Collection

Sometimes you have a pointer to an object which is re-assigned at one point, but the old object is never deleted.

  Object *foo;

  foo = new Object();
  // ... later on ...
  foo = new Object();

Which can be solved by deleting the object before re-assigning:

  Object *foo;

  foo = new Object();
  // ... later on ...
  delete foo; // <<< delete the old object
  foo = new Object();

Stage 3: Destructors

Some people assume if you make a couple of classes like this:

  class Foo
  {
    Foo();
    ~Foo();
  };

  class Woo : public Foo
  {
    Woo();
    ~Woo();
  };

If you destroy an instance of Woo both ~Woo and ~Foo will be called. Only it wont: only ~Woo will be called. Anything you free in ~Foo will never be freed.

So if you want ~Foo to be called too, the destructor for Foo needs to be virtual, i.e.:

  class Foo
  {
    Foo();
    virtual ~Foo(); // <<<
  };

Stage 4: Spaghetti

Things start getting complicated when you have objects which can be referenced by multiple objects. For example:

  Object *foo, *child1, *child2;

  foo = new Object();
  child1 = new Object();
  child1->parent = foo;
  child2 = new Object(foo);
  child1->parent = foo;

Now when do we delete foo? If we make child1 or child2 delete it, we’ll probably get a crash when we delete foo twice. If we delete it elsewhere, how do we know child1 or child2 aren’t still using it?

One possible solution is to use a reference counting system like in Objective C, so when we reach 0 we delete the object:

  class Object
  {
    Object* retain()
    {
      retainCount++; // object is being used
      return this;
    }
    void release()
    {
      --retainCount; // object is no longer being used
      if (retainCount <= 0)
        delete this;
    }
    
    virtual ~Object()
    {
      if (parent) parent->release();
    }
    
    Object *parent;
  };

  // ...

  Object *foo, *child1, *child2;

  foo = new Object();
  child1 = new Object();
  child1->parent = foo->retain(); // object is being used by child1
  child2 = new Object(foo);
  child1->parent = foo->retain(); // object is being used by child2

If you want to be more fancy you can make a smart pointer class, e.g.

  // Modified Object
  
  class Object
  {
    Object* retain()
    {
      retainCount++;
      return this;
    }
  
    void release()
    {
      --retainCount;
      if (retainCount <= 0)
        delete this;
    }
  
    virtual ~Object()
    {
      parent = NULL;
    }
  
    ObjectReference parent;
  };

  // The smart pointer

  class ObjectReference
  {
  public:
    // Constructor
    ObjectReference()
    {
      object = NULL;
    }
    
    // Assignment initializer
    ObjectReference(const ObjectReference &ref)
    {
      object = ref.object ? ref.object->retain() : NULL;
    }
    
    // Assignment operator
    ObjectReference& operator=(const ObjectReference &ref)
    {
      if (object) object->release();
      object = ref.object ? ref.object->retain() : NULL;
      return *this;
    }
    
    // Pointer operator
    operator Object*()        { return object; }
    
    Object *object; // reference to Object
  };
  
  // ...
  
  Object *foo, *child1, *child2;

  foo = new Object();
  child1 = new Object();
  child1->parent = foo; // automagically retains foo
  child2 = new Object();
  child1->parent = foo; // automagically retains foo

Beware however that when you get a circular reference your objects may never be released using this method.

Stage 5: Runaway Spaghetti

Even if you have a reference counting system, you might encounter situations where you release or retain objects too much. Typically memory leak tools only tell you where objects were allocated, not who the retain/release culprit is.

One way of solving this is to keep track of where you retain and release objects

  class Object
  {
    Object* retain(char *file=NULL, int line=0, char *owner=NULL, int addr=0) {
       retainCount++; 
       if (owner)
         printf("%x: retain (%i) [%s @ %i] OWNER %s[%x]", this, retainCount, file ? file : "", line, owner, addr);
       else
         printf("%x: retain (%i) [%s @ %i]", this, retainCount, file ? file : "", line);  
       return this;
    }

    void release(char *file=NULL, int line=0, char *owner = NULL, int addr=0) {
       --retainCount;
       if (owner)
         printf("%x: release (%i) [%s @ %i] OWNER %s[%x]", this, retainCount,file ? file : "", line, owner, addr);
       else
         printf("%x: release (%i) [%s @ %i]", this, retainCount,file ? file : "", line);
   
       if (retainCount <= 0)
         delete this;
    }
    
    // ...
  };

  // ...

  Object *foo, *child1, *child2;

  foo = new Object();
  child1 = new Object();
  child1->parent = foo->retain(__FILE__, __LINE__, "Object", child1);
  child2 = new Object(foo);
  child1->parent = foo->retain(__FILE__, __LINE__, "Object", child2);

Then you can simply examine your logs and spot the problematic line of code for that extra release or retain.

Final boss

Of course once you have solved all of your leaks, you might find you bump into the arch nemesis: Memory Corruption. Specifically, this:

  class Entity
  {
  public:
    float mNextThink;
  
    Entity();
    void think();
  };

  Entity::Entity()
  {
  
  }

What is wrong with this? Well say we have some code like this….

  for (int i=0; i<mEntities.size(); i++)
  {
    if (smCurrentTime >= mEntities[i]->mNextThink)
      mEntities[i]->think();
  }

Then think may never be called, since mNextThink is never initialized, so its value will be undefined. It could be 0, it could be -10000. Who knows. The solution is simple:

  Entity::Entity() :
  mNextThink(0) // set a default value
  {
  }

With all of your memory leaks solved, you should now be able to sleep better.

The Melancholy of Startups

Once upon a time i started working for a startup which in hindsight turned into one of the worst moments of my development career. While it certainly wasn’t all bad, it didn’t live up to expectations.

Before all of this, i thought working in a startup was quite a cool concept. Developers at the start have the power to be instrumental in developing the business and its products, so in a way it sounded like the ultimate creative effort. That combined with the potential of “The big buyout” was very attractive proposition.

Before i joined, i debated the options. Being cautious i didn’t want to go full-blown into the business, so instead i telecommuted as a freelancer with my other existing commitments.
In hindsight this was the best decision i ever made.

At first the working environment was great. I was tasked with implementing some rather cool features into the main product, working with fairly interesting people, some of whom were instrumental in improving the product.
Although i technically didn’t have any obligation to work flat out at times, i did so under the guise of making a difference.

As time went on, i ended up visiting their offices. But it was nothing like i had expected: instead of a “warm buzz” of a startup i instead found more of an awkward cold silence. Perhaps this was the first warning something wasn’t quite right.

Around this time i noticed operations were commonly micro-managed and interrupt-driven, which was ok unless you wanted to get anything done. There always seemed to be a crisis that needed resolving, so i was always on edge.

Besides that, all seemed fine until the next major iteration of the product when development focus changed.

The new focus? Crunch on getting the new release out. Ignore everything else you are doing, no excuses. I developed the dreaded “Tunnel Vision” and relentlessly worked. After all, if i wasn’t doing something, what was i there for?

As the focus on features dwindled, my main role gradually turned into the bug fixer, which from what i can tell was another way of saying “we don’t appreciate you anymore.”

The biggest demotivation came as the team decided to completely rewrite the next version using the next big thing. This effectively meant everything i had worked on and worried about for the past year had amounted to nothing.

As the startup grew, weekly meetings were introduced as a means to improve communication and determine who was working on what, which besides wasting time constantly reminded me how boring and mundane my work had become.

By this time I was suffering increasingly from stress and burnout from dealing with the startup and other commitments to make things work out.
You could probably have measured my productivity by the amount of lolcats and memes i posted into the company chatroom as a means of coping.

Eventually, things got so worse i had to take a break.

Several months later, i had a hard think: did i really want to continue working in this fashion?
The answer was no. I decided to leave for good.

Safe to say in the space of 2 years my illusion of startups being cool, fun companies to work with had been shattered.

I will probably never work for a startup ever again.

You can't pirate a web app

…or can you?

Since the dawn of consumer computing, people have pirated applications. Why should web apps be any different?

Ripping off website designs or application concepts is nothing new. Though usually maintaining such a rip-off is costly and requires a significant effort to maintain. Not to mention one is always playing cat and mouse.

I’ve noticed recently the trend towards fat clients. This is where the application is written using an MVC javascript framework (Backbone, Sproutcore, Cappuccino, etc…) and the application simply uses a JSON API on the server and renders all the views on the client.

A great deal of logic and assets are stored on the client. The server is merely used as a lightweight data storage and control system.

So if you can write a replacement server, it’s trivial to “pirate” a web service.

An example

Let’s take QuietWrite for example. A rather nice web-based text editor developed by James Yu.

If we simply save the page to disk, most of the core functionality already works!

pir-start

Of course, editing text is not very useful - we need to save it too.

pir-fin

To sum it up, within an hour i was able to replicate the backend enough so that i could save documents.

After finishing the working implementation, i was surprised to find out that James supplies the source code to an example app CloudEdit which has a similar API to QuietWrite.

I needn’t have written all that code!

Given how easy it is to deploy an app nowadays you could potentially rip off an application, stick your own ads on it, and get it running all within a day. You can even get free updates for the front-end straight from the original developer.

Provided this fat client trend continues, I wonder how long it will be till we start seeing “CD Keys”, SecuROM, and other elaborate anti-piracy solutions in web applications.

How to make a great conference

I received a bit of critique for my Review of Euruko 2011. Granted I was a bit more critical of a few things compared to my twitter feed, but well…

But what do people look for in a conference? No idea. So what do I look for in a conference?

The marketing

There’s nothing worse than hearing about a conference just when its finished. Maybe I forgot about it, or maybe I just don’t follow the right people on Twitter…

Whatever the case I really wanted to go, but since the marketing failed I missed out!

Lanyrd solves this problem partially, but not every conference is listed there. I also don’t check it regularly.

Even when I hear about an event, there are still more problems that can crop up. Quite a few times i’ve noticed events listed with poor directions. Please, tell me where your event is, otherwise I can’t get to it!

The talks

A great talk is made up of several factors, notably…

  • The speaker
  • The content
  • Relevance to the event

So I would suggest a great talk has the best speaker, with the best content which is completely related to the event.

Whereas the worst talk is narrated by the worst speaker, with the most boring content, which is completely unrelated to the event.

Personally I think this is where Barcamp-style conferences shine: there are no rules. A talk could literally be about anything. Everything is relevant.

Then again themed conferences are better in that you know what to expect when you get there. If you go to a ruby conference you get Ruby, not PHP. Not to mention the schedule is usually predetermined.

The venue

A venue can be the breaking point of the event. It needs to be large enough to accommodate the attendees. It also needs a good layout otherwise congestion will form, making everything look too crowded.

Crowds are great, until everyone starts talking and we bump into the nightclub problem: I CAN’T HEAR WHAT ANYONE IS SAYING.

Besides the specifics of the building, the venue also needs to be in an accessible location. I don’t want to trek 10 miles to the venue, and if there is no food provided people need somewhere near to go to eat.

After-events

I think after-events are also a key part of a conference. Without them your post-conference networking opportunities are limited to the people you just happened to bump into at the conference.

Its also a good opportunity for forming a lasting impression of the event in the heads of attendees. If the party last night was awesome, i’ll probably be thinking of it months down the line when the next conference is on.

Thoughts on Euruko 2011

Euruko 2011

2 weeks ago I attended the Euruko 2011 event in Berlin. In all I would say it was well worth going to, despite a few flaws.

The event was hosted in the Kino International, a cinema close to the centre of Berlin. So it was quite easy to find. Connectivity was not a problem either, as the best free wifi i’ve seen in ages was provided.

The quality of the talks was extremely varied. For instance, David Calavera’s “JRuby hacking guide” talk drew me into a state of REM sleep. In fact the next time I have insomnia, I shall be sure to seek his assistance.

In contrast to this, Paolo Perrotta’s “The Revenge of method_missing()” was a stroke of genius. Great pacing, casual tone. I found the pictures accompanying the code to be quite complimentary and hilarious.

Really, I could divide the main talks in Euruko into one of several categories.

“Here’s my code”

A talk in which the speaker meticulously describes code, a design pattern, or something equally as boring to the outside observer. Quite often the code does not have any relation to what you are doing.

“The other day…”

A talk in which the speaker tells a story with illustrations or code to accompany their points in a way which is easy to remember.

“Use my product”

The speaker describes how they solved a problem, creating a product or project in the process.

EDIT: i would also like to point out that despite my critique of the talks, overall i thought the event was great. Things such as the keynotes and the sing-along at the end were fantastic.

Enough of the talks…

Of course, a conference is more than just watching people talk in front of an impressive cinema screen. During breaks there was an opportunity to cram into the lobby area for a free drink, or to talk to one of the many developers squished against the walls.

Not to say the venue was small, but given the natural tendency of people to congregate in areas near the seating, doorways, and conference room the feeling of being in a small space was inevitable.

Predictably the free drinks and food ran out quite quickly on both days. Rather deviously someone decided to serve sparkling water next to the still water. My taste-buds still haven’t recovered.

The after-events

On both days there were events afterwards to go to. I have to say, the party at “Tante Käthe” was the most difficult thing to find, even with some helpful pointers provided by the organisers and the modern wonders of GPS.

In fact, if I had not bumped into some other attendees I would never have guessed I needed to go down a dark pathway, over a fence, round a corner and down another dark pathway.

Sadly the planned BBQ was cancelled so there was nothing to eat, though free drinks were available. To be honest though, the event itself did not live up to expectations considering you needed the skills of Indiana Jones to find it.

The second day after-event was the Github drinkup. Kudos to Github for the free drinks. However I somewhat suspect if the Github guys weren’t around, this would never have happened.

Still, drinking in a nice easy to locate venue was a great experience.

So really, was it really worth attending Euruko? Yes. It’s a great magnet for ruby developers and business people, so networking opportunities were plentiful. And there were several inspiring gems in the talks to make it worth it.

Bring on Euruko 2012!

» View more in the Archives