crashed Queue .

Tech-Archive recommends: Speed Up your PC by fixing your registry



Dear experts.
I'm testing queue source of book ( programming application in windows by
jeffrey richter )

While I'm appending and removing to and from the queue ,,, with time it
crashed
showing that
"heap .. modified .. after it freed "
I could not find anything wrong in the following code..
Any help will be appreciated..
Thanks in advance.
ck.

================================================

CQueue::CQueue(int nMaxElements)
: m_hmtxQ(m_h[0]), m_hsemNumElements(m_h[1])
{

m_pElements = (PELEMENT)
HeapAlloc(GetProcessHeap(), 0, sizeof(ELEMENT) * nMaxElements);
m_nMaxElements = nMaxElements;
m_hmtxQ = CreateMutex(NULL, FALSE, NULL);
m_hsemNumElements = CreateSemaphore(NULL, 0, nMaxElements, NULL);
}

BOOL CQueue::Append( unsigned int nUserKey, unsigned int nDataSize, void*
pData, DWORD dwTimeout) {

BOOL fOk = FALSE;
ELEMENT Ele;
Ele.nUserKey = nUserKey;
Ele.nDataSize = nDataSize;
Ele.pData = pData;

DWORD dw = WaitForSingleObject(m_hmtxQ, dwTimeout);

if (dw == WAIT_OBJECT_0) {
LONG lPrevCount;
fOk = ReleaseSemaphore(m_hsemNumElements, 1, &lPrevCount);
if (fOk) {
memcpy( &m_pElements[lPrevCount], &Ele, sizeof(ELEMENT));

} else {

SetLastError(ERROR_DATABASE_FULL);
}

ReleaseMutex(m_hmtxQ);

} else {
// Timeout, set error code and return failure
SetLastError(ERROR_TIMEOUT);
}

return(fOk); // Call GetLastError for more info
}

================================================
///////////////////////////////////////////////////////////////////////////////


BOOL CQueue::Remove(PELEMENT pElement, DWORD dwTimeout) {

// Wait for exclusive access to queue and for queue to have element.
BOOL fOk = (WaitForMultipleObjects( 2, m_h, TRUE, dwTimeout)
== WAIT_OBJECT_0);

if (fOk) {
memcpy( pElement, &m_pElements[0], sizeof(ELEMENT));

MoveMemory(&m_pElements[0], &m_pElements[1],
sizeof(ELEMENT) * (m_nMaxElements - 1));

// Allow other threads to access the queue
ReleaseMutex(m_hmtxQ);

} else {
// Timeout, set error code and return failure
SetLastError(ERROR_TIMEOUT);
}

return(fOk); // Call GetLastError for more info
}


.