Warning. This question arose because I had to work with a huge pile of awful code without proper documentation written by someone else as a research project 6 years ago. Obviously, the best solution should not cause these problems in the first place, with proper design ...
This suggests that the question is: what is the best way to get out of this situation:
- The class allocates memory on the heap and frees it in the destructor.
- Somewhere, an instance of the class is declared in the global scope.
- There is a function that initializes this instance.
- The return value of this function is used to initialize the static variable.
- A global scope variable is used outside the static scope.
Minimum working example:
File "myclass.h":
#ifndef MYCLASS_H #define MYCLASS_H #include<vector> using namespace std; class myclass{ vector<int> *onTheHeap; public: myclass(int len=0){ onTheHeap = new vector<int>(len); } ~myclass(){ delete onTheHeap; } }; #endif
file "static_loader.cpp"
#include "class.h" myclass existsForever; int cause_static_global_creation(){ existsForever = myclass(5); } static int bootstrap = cause_static_global_creation();
and file "main.cpp":
#include "class.h" extern myclass existsForever; int main(){ return 0; }
Build with:
g++ -g -c static_loader.cpp g++ -g main.cpp static_loader.o
and run as:
valgrind
Result: the variable is freed when its destructor is called in the output handler below the main one, but also in the static_initialization_and_destruction_0 function below main from static_loader!
Is there a way to ensure that these variables are released exactly once, which is not related to the need to re-encode the code? In the library I have to work with, there are several dozen copies of this template ...
EDIT:
Adding Functions:
void operator=(myclass other){ delete this->onTheHeap; this->onTheHeap = other.onTheHeap; }
and
myclass(const myclass& other){ this->onTheHeap = new vector<int>(*(other.onTheHeap)); }
Does not change behavior.
Second EDIT:
myclass& operator=(const myclass& other){ delete this->onTheHeap; this->onTheHeap = new vector<int>(*(other.onTheHeap)); return *this; }
Solves all problems. My library has a memory leak with such sources anyway, but I'm not sure how to reproduce it. At least this is not so, and thanks for the refactoring suggestions, etc.!