警告: この質問は、6 年前に研究プロジェクトとして他の誰かによって書かれた、適切なドキュメントなしで、ひどいコードの山を処理しなければならなかったために生じました。明らかに、より良い解決策は、適切な設計により、これらの問題を最初から引き起こさないことです...
とはいえ、問題は次のとおりです。このような状況から抜け出すための最良の方法は何ですか。
- クラスはヒープにメモリを割り当て、デストラクタで解放します。
- どこかで、クラスのインスタンスがグローバル スコープで宣言されています。
- このインスタンスを初期化する関数が存在します。
- その関数の戻り値は、静的変数を初期化するために使用されます。
- グローバル スコープ変数は、静的スコープ外で使用されます。
最小限の実例:
ファイル "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
ファイル「static_loader.cpp」
#include "class.h"
myclass existsForever;
int cause_static_global_creation(){
existsForever = myclass(5);
}
static int bootstrap = cause_static_global_creation();
およびファイル「main.cpp」:
#include "class.h"
extern myclass existsForever;
int main(){
return 0;
}
ビルド:
g++ -g -c static_loader.cpp
g++ -g main.cpp static_loader.o
次のように実行します。
valgrind --leak-check=full ./a.out
結果: 変数は、変数のデストラクタが終了ハンドラの main の下で呼び出されたときに解放されますが、static_loader から main の下の static_initialization_and_destruction_0 関数でも呼び出されます!
コードを大幅にリファクタリングせずに、これらの変数を 1 回だけ確実に解放する方法はありますか? 私が使用しなければならないライブラリには、このパターンのインスタンスが数十あります...
編集:
機能の追加:
void operator=(myclass other){
delete this->onTheHeap;
this->onTheHeap = other.onTheHeap;
}
と
myclass(const myclass& other){
this->onTheHeap = new vector<int>(*(other.onTheHeap));
}
動作を変更しません。
2番目の編集:
myclass& operator=(const myclass& other){
delete this->onTheHeap;
this->onTheHeap = new vector<int>(*(other.onTheHeap));
return *this;
}
すべての問題を解決します。とにかく、私のライブラリにはこのようなソースでメモリリークがありますが、それを再現する方法がわかりません. 少なくともこれではありませんが、リファクタリングなどの提案にも感謝します!