我最近在调试一个程序,主要解决实时采集存储。采用多线程的方法实现,但一直出现内存访问违例崩溃。
先把程序框架分析一下:程序:MFC WIN32, 开发环境:VS2005, 处理器AMD Athlon64(tm)X64 dual,操作系统32位WinXP,编译目标X86程序通过一个回调函数以一定的帧率采集图像,我开辟一个工作者线程,并设置了一个BUFFERSIZE(常量)大小的环形缓冲区,每个缓冲区单元是一个帧结构。然后调用如下函数开辟一个工作者线程和一个semaphore用于同步,
hSemaphore = CreateSemaphore(NULL, 0, 3, NULL);
pWorkThrd = AfxBeginThread(ThreadFunc,
(LPVOID) 1,
THREAD_PRIORITY_ABOVE_NORMAL,
CREATE_SUSPENDED);
ASSERT(pWorkThrd );
// Not let the thread terminate by itself
pWorkThrd->m_bAutoDelete = FALSE;
pWorkThrd->ResumeThread();
在工作者线程函数ThreadFunc中等待信号灯激发,并实现对缓冲区内容的硬盘写入操作;而回调函数中负责内存的搬运工作;
但是每次只能正常运行BUFFERSIZE(即缓冲区大小)次数的正确内存拷贝,然后就发生内存访问违例异常。
被这个问题困扰了很久,希望了解的人能够帮忙回答一下。先说谢谢了。
先把程序框架分析一下:程序:MFC WIN32, 开发环境:VS2005, 处理器AMD Athlon64(tm)X64 dual,操作系统32位WinXP,编译目标X86程序通过一个回调函数以一定的帧率采集图像,我开辟一个工作者线程,并设置了一个BUFFERSIZE(常量)大小的环形缓冲区,每个缓冲区单元是一个帧结构。然后调用如下函数开辟一个工作者线程和一个semaphore用于同步,
hSemaphore = CreateSemaphore(NULL, 0, 3, NULL);
pWorkThrd = AfxBeginThread(ThreadFunc,
(LPVOID) 1,
THREAD_PRIORITY_ABOVE_NORMAL,
CREATE_SUSPENDED);
ASSERT(pWorkThrd );
// Not let the thread terminate by itself
pWorkThrd->m_bAutoDelete = FALSE;
pWorkThrd->ResumeThread();
在工作者线程函数ThreadFunc中等待信号灯激发,并实现对缓冲区内容的硬盘写入操作;而回调函数中负责内存的搬运工作;
但是每次只能正常运行BUFFERSIZE(即缓冲区大小)次数的正确内存拷贝,然后就发生内存访问违例异常。
被这个问题困扰了很久,希望了解的人能够帮忙回答一下。先说谢谢了。
多线程的话。建议使用GlobalAlloc,GlobalFree如果是new出来的。还是开辟一个足够大的静态内存区域吧。我说的是全局的。
这个是我的结构:
typedef struct _FRAMENODE_
{
_FRAMENODE_ *pNext;
FRAMEINFO frameInfo;
CRITICAL_SECTION critical_sec;
}FrameNode, *PFrameNode;其中FAMEINDO是另外一个struct,记录帧信息,重要的是有一个指向帧内容的指针lBufPtr。下面是我在主线程的消息响应函数里分配内存的代码:
其中,m_pFrameBuffer是指向环形缓冲区开始的标记指针,m_pCurDispFrame是当前显示指针,同时用来操作环形缓冲区的初始化。lBufSizeG是在准备阶段获得的需要缓冲区单元大小(该数据经验证没有问题),CRITICAL_SECTION 我注释掉测试过,也一样发生问题。
if(NULL == m_pFrameBuffer)
{
FrameNode *pTempNode = new FrameNode;
if(!pTempNode)
AfxMessageBox("Create FrameNode failed");
pTempNode->pNext = NULL;
pTempNode->frameInfo.lBufPtr = new BYTE[lBufSizeG];
if(!pTempNode->frameInfo.lBufPtr)
AfxMessageBox("Create Buffer failed!");
m_pFrameBuffer = pTempNode;
m_pCurDispFrame = m_pFrameBuffer;
m_pCurSaveFrame = m_pFrameBuffer;
//Initialize CriticalSection
InitializeCriticalSection(&pTempNode->critical_sec);
#ifdef _DEBUG
OutputDebugString(" Allocate a buffer!");
#endif
}
for(int i = 0; i< BUFFERSIZE-1; i++)
{
FrameNode *pTempNode = new FrameNode;
pTempNode->pNext = NULL;
pTempNode->frameInfo.lBufPtr = new BYTE[lBufSizeG];
//InitializeCriticalSection(&pTempNode->critical_sec);
m_pCurDispFrame->pNext = pTempNode;
m_pCurDispFrame = pTempNode;
#ifdef _DEBUG
OutputDebugString(" Allocate a buffer!");
#endif
} m_pCurDispFrame->pNext = m_pFrameBuffer;
m_pCurDispFrame = m_pFrameBuffer;还是需要大家多多帮助呀。今天一天在线等。
new 使用 malloc申请内存。
你把指针给了下面的变量?
m_pCurDispFrame->pNext = pTempNode;
m_pCurDispFrame = pTempNode; 怎么没有见过你delete?
是否在不同的线程中delete?
如果是的。又不想改程序那么把afxmem.cpp当中的
new函数.malloc 和 _malloc_dbg
delete函数 free 和 _free_dbg
修改为GlobalAlloc和GlobalFree看看。
我在同一个主线程delete的,就是结束的消息响应函数中做的。
在同一个进程中应该不存在权限的问题呀。我遇到的情况是对于申请的Heap第一次是可以访问的,但第二次再访问就发生崩溃了,就是访问非法。
Dword_align:
test edi,11b ;U - destination dword aligned?
jnz short CopyLeadUp ;V - if we are not dword aligned already, align shr ecx,2 ;U - shift down to dword count
and edx,11b ;V - trailing byte count cmp ecx,8 ;U - test if small enough for unwind copy
jb short CopyUnwindUp ;V - if so, then jump rep movsd ;N - move all of our dwords
jmp dword ptr TrailUpVec[edx*4] ;N - process trailing bytes在红色那里崩溃了
Output的exception是Access violation writing location 0xaddress源代码中的memcppy调用是:
memcpy(m_pCurDispFrame->frameInfo.lBufPtr,
DstFrameInfo.lBufPtr, (size_t)DstFrameInfo.lBufSize);然后我用GlobalAlloc函数了,也是一样的崩溃。
所有的内存都只能正确访问一次,再访问出错。