Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ static class member, who cleans up the mess?

Tags:

c++

memory

I was wondering which part of my code will free a dynamically allocated, but static class member when this is not needed anymore. See the following code: classPrinter is shared among all A-objects and created when the first instance of class A will be created. Just to be sure: the classPrinter-object will automatically be destructed when exiting my program, right?

a.h

class A {
static B* classPrinter;
}

a.cpp

#include "a.h"
B A::classPrinter = new B();

A::A() { ...}
like image 295
Eric Avatar asked Dec 20 '11 15:12

Eric


3 Answers

Just to be sure: the somePrinter-object will automatically be destructed when exiting my program, right?

Since this is C++, the answer is "No." For everything allocated with new the corresponding delete must be called. If that doesn't happen, the object leaks. But why allocate this dynamically at all? This

class A {
  static B classPrinter;
}

B A::classPrinter;

behaves like your code, except that classPrinter will be destructed at the end of the program.

However, you write that

classPrinter is shared among all A-objects and created when the first instance of class A will be created.

The code in your question doesn't do this. If you want to do this, do something like this:

class A {
  static std::shared_ptr<B> classPrinter;
}

std::shared_ptr<B> A::classPrinter;

A::A()
{
  if(!classPrinter)
    classPrinter.reset(new B());
}

The smart pointer will make sure that the object gets deleted.

like image 195
sbi Avatar answered Oct 05 '22 01:10

sbi


No, objects created using new are never automatically deleted. You should always provide a matching delete to prevent memory leaks.

In this case, the simplest solution would be to have a static object, rather than a static pointer to a dynamic object - there is no reason at all for the extra level of indirection.

// header file
class A {
    static B classPrinter;
};

// source file
B A::classPrinter;

or if you want to delay the construction until the object is needed (and avoid potential problems if static objects in other translation units need to access it from their constructors):

class A {
    static B & classPrinter() {
        static B instance;
        return instance;
    }
};

In other situations, when you actually need dynamic allocation, you should always manage the dynamic object using smart pointers or other RAII objects.

like image 40
Mike Seymour Avatar answered Oct 05 '22 00:10

Mike Seymour


The destructor of the object of which A::classPrinter points to will not be called.

If you think about it's nothing else but logic; where is the matching delete-statement that, in normal cases, would call the dtor of the object?

The memory occupied will be flagged as free again and returned to the system, at least in all modern such.

like image 31
Filip Roséen - refp Avatar answered Oct 05 '22 01:10

Filip Roséen - refp