1

私は現在、C ++ dllのシェルを構築する必要があるプロジェクトに取り組んでいるため、新しいC#GUIでその機能を使用できます。ただし、次の問題が発生しました。C++の部分では、特定の理由で新しいスレッドを作成する必要があり、int配列を新しいスレッドに渡したいと考えています。これが発生する関数で配列に割り当てられた値は、コードのC#部分から取得されることに注意してください。

__declspec( dllexport ) void CreateReportPane(int &id, int &what)
{
    DWORD threadId; 
    int iArray[2] = { id, what};    

    HANDLE hThread = CreateThread( NULL, 0, CreateReportPaneThread, iArray, 0,  &threadId);
    if (hThread == NULL) 
    {           
        ExitProcess(3);
    }    
}

新しいスレッドで問題が発生し、配列から最初の値を確実にフェッチできますが、2番目の値が解放されているようです。これが反対側のコードです。

DWORD WINAPI CreateReportPaneThread(LPVOID lparam)
{
    int id, what;
    id = *(( int * )lparam);
    what = *(((int *)lparam)+1) ; 
    CreateReportPaneOriginal(id, what);

    return 0;
}

元のスレッドを拘束していないときに配列の値が解放されないようにする方法はありますか?よろしくお願いします

4

2 に答える 2

3
int iArray[2] = { id, what};    

HANDLE hThread = CreateThread(...,CreateReportPaneThread, iArray, ...);

問題はiArray、ローカル配列であるということです。これは、関数CreateReportPane()が戻るときにこれが破棄されることを意味します。したがって、CreateReportPaneThread()参照するものは存在しません。たまたま最初の値を取得します。最初の値でさえも得られるという保証はありません。

動的配列を使用します。

int * iArray  = new int[2];
iArray[0] = id;
iArray[1] = what;

HANDLE hThread = CreateThread(...,CreateReportPaneThread, iArray, ...);

配列の割り当てを解除したら、次のように記述してCreateReportPaneThreadください。

DWORD WINAPI CreateReportPaneThread(PVOID *data)
{
     int *array = static_cast<int*>(data);

     int id = array[0], what = array[1];

     delete []array; //MUST DO IT to avoid memory leak!

     //rest of your code
}
于 2012-11-08T09:07:26.040 に答える
2

CreateReportPane()配列を動的に割り当てて、終了時に配列がスコープ外になるのを防ぎます。

int* iArray = new int[2];
iArray[0] = id;
iArray[1] = what;    

それ以外の場合、スレッドは無効な配列にアクセスしています。これは未定義の動作です。スレッドルーチンCreateReportPaneThread()は、delete[]不要になったときに配列を配列する必要があります(の使用とではないことに注意してくださいdelete[]delete

于 2012-11-08T09:06:29.727 に答える