何度考えてもよくわからなかった 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) {
    PVAL tmp;
    std::string sav;
    ThreadCount++;
    tmp=(PVAL)datax;
    if(tmp->data==1){
        sav=tmp->data;
           :
     }
    delete tmp;
    ThreadCount--;
    _endthread();
}


このコード中で、 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) {
    PVAL tmp;
    char abc[128];
    ThreadCount++;
    tmp=(PVAL)datax;
    if(tmp->data==1){
        std::string sav;
        sav=tmp->data;
           :
     }
    delete tmp;
    ThreadCount--;
    _endthread();
}

えー、理由がさっぱりわからないよ!|;・ω・)
実際のコードでは、配列やら、いろいろ使っているのですが、リソースリークを起こしてるのは std::string だけ。
スレッド開始時に、std::string で確保したデータはブロック内でスレッド終了すると、もしかしてリソースリークになるんだろうか?

と思って、検索したら仲間がいたよ。

2005-09-19 - いろきゅう.jp ~Programmable maiden~ Tech side
its55 lab » スレッドを_endthreadで終わったらメモリリーク
Ereyの独り言

どうやら、スレッドを_endthreadで強制終了させると、CString(MFC)や std::string (SDK)のデストラクタがコールされないらしい。

なんてこったい。

_endthread、_endthreadex (CRT)

_endthread または _endthreadex を明示的に呼び出すと、スレッドを終了できます。ただし _endthread または _endthreadex は、_beginthread_beginthreadex のパラメータとして渡されたルーチンからスレッドが戻ると自動的に呼び出されます

指定しなくても、一応自動的に終了されるそうだ。

_beginthread、_beginthreadex (CRT)

_beginthread よりも _beginthreadex を使用した方が安全です。_beginthread によって生成されたスレッドの終了が早すぎると、_beginthread の呼び出し元に返されるハンドルが無効になる可能性や、別のスレッドを指す可能性があります。しかし、_beginthreadex から返されるハンドルは _beginthreadex の呼び出し元で閉じられる必要があるため、_beginthreadex がエラーを返さなかった場合にはハンドルが有効であることが保証されます。

こういう情報も。ふむふむ。参考になるなぁ

おすすめ

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です