Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sequential new & delete

In continuation to my previous question, I would like to ask the following :

Given a C++ function having a new statement in it but not returning anything explicitly (i.e. with a return statement), should it also always have a delete?

If no, could you please give me an example.

like image 217
tao Avatar asked Dec 22 '22 11:12

tao


2 Answers

It doesn't have to explicitly return the newly-created object, but it should pass it to something else in some way. Possible scenarios include:

  • In a member function, create an object and assign it to a field of the containing object.

Example:

class Foo {
    private:
        Baz* baz;
    public:
        Foo() : baz(0) { }
        void create_bar() { baz = new Baz(); }
        ~Foo() { delete baz; }
};
  • Passing the new object to something else.

Examples:

void foo() {
    // assuming bar lives in the global scope
    bar.baz = new Baz();
}

void foo2(Bar& bar) {
    bar.baz = new Baz();
    // or, better:
    bar.setBaz(new Baz());
}
  • Using some kind of garbage-collecting pointer type.

Example:

std::auto_ptr<Baz> foo() {
    return new Baz();
}
  • Passing the pointer into another function that does something with it and then deletes it.

Example:

void foo(Bar* bar) {
    bar->dostuff();
    delete bar;
}

void baz() {
    Bar* bar = new Bar();
    foo(bar);
}
like image 170
tdammers Avatar answered Dec 24 '22 00:12

tdammers


The rule with new is very simple: the pointer returned by new must be deleted at some point by someone, somewhere in the code. If the pointer returned by new is lost, forgotten, or discarded, then you have a memory leak, and that is bad.

Therefore, if you new up some memory and return without storing it anywhere permanently, then you have leaked memory. Therefore, if you aren't going to delete it, then the pointer must be either stored in some kind of long-term storage (member of a class, static variable, etc) or it must be returned so that someone else can delete it.

Alternatively, you can just use a boost::shared_ptr and stop caring about (most of) this.

like image 36
Nicol Bolas Avatar answered Dec 24 '22 02:12

Nicol Bolas