何度考えてもよくわからなかった std::string のメモリーリーク
もふったーの開発で、メモリリークが発生するどうしてもわからない場所を突き止めたら、次のようなコードでした
int ThreadCount=0; int main(){ VAL *vals; vals=new VAL; vals->mode=1; vals->data="testdata"; _beginthread(ThreadMain,0,vals); } void ThreadMain(void *datax) { |
このコード中で、 std::string sav がなぜか終了時に、リソースリーク。
苦し紛れに次のようなコードにしたら、出なくなったよ。
int ThreadCount=0; int main(){ VAL *vals; vals=new VAL; vals->mode=1; vals->data="testdata"; _beginthread(ThreadMain,0,vals); } void ThreadMain(void *datax) { |
えー、理由がさっぱりわからないよ!|;・ω・)
実際のコードでは、配列やら、いろいろ使っているのですが、リソースリークを起こしてるのは std::string だけ。
スレッド開始時に、std::string で確保したデータはブロック内でスレッド終了すると、もしかしてリソースリークになるんだろうか?
と思って、検索したら仲間がいたよ。
2005-09-19 - いろきゅう.jp ~Programmable maiden~ Tech side
its55 lab » スレッドを_endthreadで終わったらメモリリーク
Ereyの独り言
どうやら、スレッドを_endthreadで強制終了させると、CString(MFC)や std::string (SDK)のデストラクタがコールされないらしい。
なんてこったい。
_endthread または _endthreadex を明示的に呼び出すと、スレッドを終了できます。ただし _endthread または _endthreadex は、_beginthread や _beginthreadex のパラメータとして渡されたルーチンからスレッドが戻ると自動的に呼び出されます |
指定しなくても、一応自動的に終了されるそうだ。
_beginthread、_beginthreadex (CRT)
_beginthread よりも _beginthreadex を使用した方が安全です。_beginthread によって生成されたスレッドの終了が早すぎると、_beginthread の呼び出し元に返されるハンドルが無効になる可能性や、別のスレッドを指す可能性があります。しかし、_beginthreadex から返されるハンドルは _beginthreadex の呼び出し元で閉じられる必要があるため、_beginthreadex がエラーを返さなかった場合にはハンドルが有効であることが保証されます。 |
こういう情報も。ふむふむ。参考になるなぁ
Comments