0

アプリケーションからアクセス違反が発生しました。

コールスタック:

0da0ccfc 77c46fa3 ntdll!KiUserExceptionDispatcher+0xe 
0da0d004 4dfeee3a msvcrt!memcpy+0x33 
0da0d45c 4dfdbc4b MyLibrary!MyClass::MyFunc+0x8d [MyFile.cpp @ 574]

[MyFile.cpp @ 574 memcpy( m_pMyPointer, m_pSrcPointer, m_nDataSize);

ここで、次のことを確信しています.. m_pMyPointer は有効であり、他のスレッドはこのメモリを読み書きしません。m_pMyPointer のサイズが m_nDataSize を超えています。m_pSrcPointer は他のスレッド (読み取りまたは書き込み) からアクセスできますが、m_pSrcPointer のサイズが m_nDataSize より小さい可能性はほとんどありません。

私の疑問は、他のスレッドが m_pSrcPointer への読み取り/書き込みを試みた場合、memcpy(m_pMyPointer, m_pSrcPointer, m_nDataSize) からアクセス違反を取得する可能性があるかどうかです。memcpy() は m_pSrcPointer を読み取り、書き込みはしないため..

4

3 に答える 3

1

私はそれを除外します。メモリ領域への同時読み取りアクセスは、定義上、スレッドセーフです。あるスレッドが別のスレッドによって読み取られるメモリの場所に書き込むと、結果が予測できないという意味でスレッドセーフが失われますが、アクセス違反は発生しません(x86を含むほとんどの正常なプラットフォームで)。

ほとんどの場合、またはのいずれかが指す有効なメモリ領域のサイズは。よりも小さくなります。m_pMyPointerm_pSrcPointerm_nDataSize

ただし、同じメモリが異なるスレッドによって同時に読み書きされることに疑問がある場合は、少なくともそこでのロックスキームが欠落していることを意味します。

于 2012-10-01T05:30:26.770 に答える
1

並行スレッドがバッファー内のデータのみを変更する場合、バッファーとの間でコピーを行って AV を取得するべきではありません。

並行スレッドがバッファーへのポインターまたはバッファーのサイズ (バイト数または要素数) を含む変数を変更する場合、これらのポインターおよびサイズ変数を使用して、バッファーとの間でコピーすることで簡単に AV を取得できます。ここで、未定義の動作の土地に入ります。

于 2012-10-01T05:50:18.630 に答える
0

小さな可能性があります。m_srcPtrへの書き込みがアトミックでない場合、または他のスレッドが他のメンバーの1つに書き込みを行っていて、それについて通知していない場合(たとえば、m_nDataSizeはありそうなことのように聞こえます)。

m_srcPtrへの書き込みがアトミックでない場合、アーキテクチャによっては、ポインターへの2回の書き込みの間に一時的に無効なポインターが存在する可能性があります。m_nDataSizeがm_srcPtrと同時に「同時に」更新されると、悪いことが起こる可能性が十分にあります。

これはアーキテクチャに大きく依存することに注意してください。

于 2012-10-01T09:05:54.083 に答える