Out with the new!

Before I became a C++ developer, I wrote a lot of Java, and I mean a LOT. When I was unemployed I wrote a point of sale system, a stock management system a web servlet app. I wrote pretty much everything in Java back then.

Then I learned C++, and I didn’t know that you could write C++ in a Java fashion.  Indeed my mentor at the time saw some code I wrote and just like a Java developer I put everything in one file within a class.

And wouldn’t you know it, now I’m the mentor and I’m finding my mentee is doing the exact same thing. And some may say why is that bad? It all has to do with a simple word. And that word is, new.

In Java if you wanted to create an object, you’d do something like this:

static void main(String args[])
{
    Person fred = new Person();
    fred.doSomething();
}

This looks all nice and dandy doesn’t it.  You simply create a new person object, and then forget about it. Now I want to point out that in Java, this IS NOT a bad thing. Java has a special mechanism to deal with this called Garbage Collection, which is something that runs periodically and checks for objects that have not been used, or since gone out of scope and deletes them.

However, C++ doesn’t have this feature. (Well not as such, but it’s beyond the scope of this blog post). C++ is a very powerful language, and it trusts that you know what you’re doing and this is true of object management.

C++ doesn’t clear down objects for you, you’ve got to do that yourself. In C++ for every, yes EVERY object that’s created with the keyword new, there MUST be a corresponding delete for it.

So consider the following code:

int main()
{
    Person* p1 = new Person();
    p1->doSomething();
    // now we're done with the person object.
    delete p1;
}

The above code not only creates a person object, but also deletes it.  An important thing to learn also is to delete things in the reverse order you create them. It’s considered good practice, and can prevent possible undefined behaviour.

The other thing new does, is that it creates your object on the heap. “So what?” I hear you ask. Well, let me explain a little about why this isn’t ALWAYS what you want…

A very quick note on stacks and heaps…

When you write a program, it can be stored in one of two places in memory. The stack, and the heap.

The stack is memory that’s allocated for a thread of execution. So for example, when your function is called, a block is reserved on top of the stack for local variables and some data pertaining to your function. When the function returns or hits the last brace, the block is then freed automatically and can be used for another function. Imagine if you will a stack of plates in a cafeteria, a memory stack is identical. Last one In, First one Out otherwise known as LIFO. So the most recently used block is always going to be the one that’s freed.

Stacks don’t tend to be that big, so you wouldn’t want to put a 512Mb vector on there for example. That’s what the heap is for.

The heap is a chunk of memory that’s allocated for dynamic allocation. There’s no enforced pattern like there is on the stack, on the heap you allocate your data pretty much where you want, as long as it’s contiguous space big enough to hold your data.

This is where your data is put when you use the new keyword in your code, and if you don’t call delete on your new’d object, then it will stay in memory thus swallowing up some resource.

So what are the options?

Now that we know where new’d objects go, what are the alternatives?  Well you can create stuff on the stack, however as previously mentioned, the stack isn’t as big as the heap. So we must be judicious in where in memory we place our objects. So for example, if you have a class object that you know is going to have a massive vector of objects in it, then place it in the heap using the new keyword.  Otherwise, put it in the stack.  One of the main benefits of this approach is that you don’t have to worry about deleting it, because as soon as your function hits the last curly brace, it’s popped and released from the stack.

To place something on the stack you’d do the following:

int main()
{
    // let's say that we have a person that takes a string as it's constructor
    // argument, you'd declare it thus:
    Person student("Joe Bloggs");

    // For a default constructor with no params you'd do thus:
    ConfigurationManager config;
}

Both these place objects on the stack rather than the heap.

Another option available to you, if you use a modern compiler (and why shouldn’t you?) is the use of smart pointers.  These have been around for some time now, but they almost (I’m not 100% sure) act like an object created with the new keyword in Java in that the second they go out of scope, their destructors are called and the object is destroyed. Now while this may sound similar to garbage collection, I’m reliably informed that it isn’t.

However there are a number of smart pointers that can be used.

unqiue_ptr is a smart pointer that holds sole ownership of an object via a pointer and will destroy it once the pointer goes out of scope. You can’t have a uniqe_ptr pointing to two objects. The code sample below shows a very basic demo of unique_ptr.

class someHugeObject
{
    // a whole bunch of functions in here....
public:
    void someFunction();
};

void doSomethingWithObject()
{
    std::unique_ptr<someHugeObject> huo(new someHugeObject());
    huo->someFunction();
}  // then huo is deleted when we get to this line.  Even though we've used the new keyword.

shared_ptr is, as the name suggests a pointer that allows you to have multiple pointers pointing to the same piece of memory. So you could have many objects sharing the same block of memory. But unlike a unique_ptr, the object is destroyed under the following circumstances:

a) The last remaining shared_ptr owning the object is destroyed or b) the last remaining shared_ptr that owns the object is assigned another pointer

std::shared_ptr<Person> p1(new Person("Fred Jones")); // we create a new person
std::shared_ptr<Person> p2 = p1;  // now p2 has access to the person in p1

// so if we do:
p1.reset();  // the Person will still exsist because p2 is still pointing to it.
p2.reset();  // the last reference to the memory block has gone, so it now gets removed.

So in conclusion then, I can still hear my mentor’s words in my ear when he told me that I should never use new. And looking at this, you could say there’s a strong case for not doing so.  However I’d like to say:

Use the stack when you can, but when you need to, use the heap.  Also don’t be afraid to play, spool a VM, have a play, cause a stackoverflow and see what happens. It’s the best way to learn.

Happy coding people Smile

Advertisements

About welshboy2008

In my spare time, I read, listen to music, play my guitar among other stuff. I love to write computer programs too. In various languages. But mostly C# and Java. I'm currently learning: PHP, Javascript, XML, ASP.NET, Python, C and Assembler.

Posted on 10/04/2015, in Uncategorized. Bookmark the permalink. Leave a comment.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: