I ran across this issue in my application after checking it for memory leaks, and discovered that some of my classes are not being destroyed at all.
The code below is split into 3 files, it is supposed to implement a pattern called pimpl. The expected scenario is to have both Cimpl constructor and destructor print their messages. However, that’s not what I get with g++. In my application, only constructor got called.
classes.h:
#include <memory>
class Cimpl;
class Cpimpl {
std::auto_ptr<Cimpl> impl;
public:
Cpimpl();
};
classes.cpp:
#include "classes.h"
#include <stdio.h>
class Cimpl {
public:
Cimpl() {
printf("Cimpl::Cimpl()\n");
}
~Cimpl() {
printf("Cimpl::~Cimpl()\n");
}
};
Cpimpl::Cpimpl() {
this->impl.reset(new Cimpl);
}
main.cpp:
#include "classes.h"
int main() {
Cpimpl c;
return 0;
}
Here is what I was able to discover further:
g++ -Wall -c main.cpp
g++ -Wall -c classes.cpp
g++ -Wall main.o classes.o -o app_bug
g++ -Wall classes.o main.o -o app_ok
It looks like the destructor is being called in one of two possible cases, and it depends on the linking order. With app_ok I was able to get the correct scenario, while app_bug behaved exactly like my application.
Is there any bit of wisdom I am missing in this situation?
Thanks for any suggestion in advance!
The goal of the pimpl idiom is to not have to expose a definition of the implementation class in the header file. But all the standard smart pointers require a definition of their template parameter to be visible at the point of declaration in order to work correctly.
That means this is one of the rare occasions where you actually want to use
new,delete, and a bare pointer. (If I’m wrong about this and there’s a standard smart pointer that can be used for pimpl, someone please let me know.)classes.h
classes.cpp