3

私は、.h ファイルで定義されているクラス クラス demo のオブジェクトを渡す新しいスレッドを作成しています。

int threadentry(void* data)
{
   demo* inst=(demo*) data;
   cout << "Value of inst  "<<hex << &inst<< endl;//value is different from below
}

int main()
{
while(1)
{
    demo* inst=new demo();
    cout << "Value of inst  "<<hex << &inst<< endl;  //value is coming different from above
    HANDLE threads;
    DWORD threadId1;
    if ((threads = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadentry,
        (void *)inst, 0, &threadId1)) == NULL)
        return -1;
    delete inst;
    system("pause");
}
}

threadentryのデータ変数にアドレスがコピーされているので、値が違うはずだと思います。これらが渡された同じオブジェクトであることを確認するにはどうすればよいですか。

4

2 に答える 2

5

コードは、オブジェクトのアドレスではなく、ポインターのアドレスを出力しています。関連する 2 つのポインター変数 (1 つはスレッド関数で宣言されmain()、もう 1 つはスレッド関数の引数) があるため、出力は異なります。&出力ステートメントから、演算子のアドレスを削除します。

cout << "Value of inst  "<<hex << inst << endl;

提供されたオブジェクトの所有権を、スレッドがいつ使用を終了したかを知っているスレッドに渡します。投稿されたコードでは、スレッドの作成後にオブジェクトが削除されるため、スレッドがダングリング ポインターを使用する可能性があります。オブジェクトの削除をメインからスレッドに移動します。

スレッド関数のシグネチャは次のとおりです。

DWORD WINAPI ThreadProc(
  _In_  LPVOID lpParameter
);

値を返す必要がありますが、投稿されたコードはそうではありません。

から返されたハンドルCreateThread()が閉じられていないため、コードにはリソース リークもあります。CloseHandle()スレッドを結合する必要がない場合はただちにスレッ​​ド ハンドルを格納するか、たとえばstd::vector(たとえばを使用して) 結合してWaitForSingleObject後で閉じるためにスレッド ハンドルを格納します。

于 2013-07-16T05:39:40.790 に答える
2

競合状態になる可能性があります。の直後にクラス インスタンスを削除しますCreateThread。この時点でthreadentry()は、まだ実行を開始していない可能性があります。

于 2013-07-16T05:41:54.250 に答える