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

如果并发线程仅更改缓冲区中的数据,则不应通过从缓冲区复制/向缓冲区复制来获取任何 AV。

如果并发线程更改指向缓冲区的指针或包含缓冲区大小(字节数或元素数)的变量,您可以使用这些指针和大小变量轻松地从缓冲区复制到/从缓冲区中获取 AV。在这里,您正在进入未定义行为的领域。

于 2012-10-01T05:50:18.630 回答
1

我会排除这一点。根据定义,对内存区域的并发读取访问是线程安全的。当一个线程写入由另一个线程读取的内存位置时,您将失去线程安全性,因为结果是不可预测的,但您仍然不应该遇到访问冲突(在大多数健全的平台中,包括 x86)。

最有可能的是或指向的有效内存区域的大小小于。m_pMyPointerm_pSrcPointerm_nDataSize

但是,如果您怀疑不同线程同时读取和写入同一块内存,这意味着您至少错过了那里的锁定方案。

于 2012-10-01T05:30:26.770 回答
0

可能性很小。如果对 m_srcPtr 的写入不是原子的,或者另一个线程正在写入其他成员之一而您没有告诉我们这件事(例如,m_nDataSize 听起来很可能)。

如果对 m_srcPtr 的写入不是原子的,则取决于您的体系结构,您可能会在两次写入指针之间临时有一个无效指针。如果 m_nDataSize 与 m_srcPtr “同时”更新,则您有很多机会发生坏事。

请注意,这是高度依赖于架构的。

于 2012-10-01T09:05:54.083 回答