PDA

View Full Version : memory corruption



Rambobino
10th August 2010, 20:21
Hi,

I'm having a problem here and I wonder if someone can help me:

I have an Email Notification class which inherits from QThread so the email sending does not block the main thread. The function that sends notifications can be called from various location in the program so I've created a small Ring buffer class which stores quint32 then I add the email details in a struct and store the address of the struct in the ring buffer. Then the run() function loops through the ring buffer and sends the emails.

The problem I'm having is that as soon as I call the function once and then close the application (in Debug mode), I get a message saying "Unhandled exception at 0x009eb9df in MyApp.exe: 0xC0000005: Access violation writing location 0xfeeefeee." and the Call Stack shows me a random location each time as if the memory would be corrupted and anything would crash.

Here are the two functions that are called:


bool CNotification::sendAlertNotification(QStringList qszEmailTo, QString qszAlert)
{
if(isNotificationEnabled() == false)
{
return false;
}

SNotificationData *pNotData = new SNotificationData;
pNotData->qszTo = qszEmailTo;
pNotData->qszBody = qszAlert;

m_ringBuffer.put((quint32)pNotData);

start();

return true;
}

void CNotification::run()
{
QMutexLocker locker(&m_mutex);

while(m_ringBuffer.level() > 0)
{
SNotificationData *pNotData = (SNotificationData*)m_ringBuffer.get();

// --> removed the email sending code from here but it crashes anyway

delete pNotData, pNotData = 0;
msleep(100);
}
}

Do you think it's because I create the structs on the heap in the main thread and then delete them in the new thread? And how could I code it for it to work then?

Thanks a lot!
Simon

**EDIT**
Here's the code of the ring buffer class, it can maybe help someone else

RingBuffer32.cpp


#include "RingBuffer32.h"

CRingBuffer32::CRingBuffer32()
: m_uLevel(0),
m_uDepth(0),
m_pR(0),
m_pW(0),
m_pBuffer(0)
{

}

CRingBuffer32::~CRingBuffer32()
{
if(m_pBuffer)
{
delete[] m_pBuffer;
m_pBuffer = 0;
}
}

void CRingBuffer32::initialize(quint32 uDepth)
{
m_uLevel = 0;
m_uDepth = uDepth;

if(m_pBuffer)
{
delete[] m_pBuffer;
}

m_pBuffer = new quint32[m_uLevel];

m_pR = m_pBuffer;
m_pW = m_pBuffer;
}

void CRingBuffer32::uninitialize()
{
m_uLevel = 0;
m_uDepth = 0;
m_pR = 0;
m_pW = 0;

if(m_pBuffer)
{
delete[] m_pBuffer;
m_pBuffer = 0;
}
}

void CRingBuffer32::clear()
{
m_uLevel = 0;
m_pR = m_pBuffer;
m_pW = m_pBuffer;
}

quint32 CRingBuffer32::getStat()
{
if(m_uLevel >= m_uDepth)
{
return Stat_Full;
}

if(m_uLevel == 0)
{
return Stat_Empty;
}

return Stat_HasData;
}

quint32 CRingBuffer32::level()
{
return m_uLevel;
}

quint32 CRingBuffer32::put(quint32 u)
{
if(m_uLevel < m_uDepth)
{
*m_pW++ = u;

if(m_pW >= (m_pBuffer + m_uDepth))
{
m_pW = m_pBuffer;
}

m_uLevel++;

return u;
}
else
{
return (quint32) -1;
}
}

quint32 CRingBuffer32::get()
{
quint32 u;

if(m_uLevel > 0)
{
u = *m_pR++;

if(m_pR >= (m_pBuffer + m_uDepth))
{
m_pR = m_pBuffer;
}

m_uLevel--;

return u;
}
else
{
return (quint32) -1;
}
}

quint32 CRingBuffer32::write(quint32 *pSrc, quint32 uCount)
{
quint32 i = 0;

while(i < uCount)
{
if(m_uLevel < m_uDepth)
{
*m_pW++ = *pSrc++;

if(m_pW >= (m_pBuffer + m_uDepth))
{
m_pW = m_pBuffer;
}

m_uLevel++;
i++;
}
else
{
return i;
}
}

return i;
}

quint32 CRingBuffer32::read(quint32 *pDest, quint32 uCount)
{
quint32 i = 0;

while(i < uCount)
{
if(m_uLevel > 0)
{
*pDest++ = *m_pR++;

if(m_pR >= (m_pBuffer + m_uDepth))
{
m_pR = m_pBuffer;
}

m_uLevel--;
i++;
}
else
{
return i;
}
}

return i;
}

RingBuffer32.h


#ifndef RINGBUFFER32_H
#define RINGBUFFER32_H

#include <QObject>

class CRingBuffer32
{
public:

enum
{
Stat_Empty=0,
Stat_HasData=1,
Stat_Full=2
};

CRingBuffer32();
~CRingBuffer32();

void initialize(quint32 uDepth);
void uninitialize();
void clear();
quint32 getStat();
quint32 level();
quint32 put(quint32 u);
quint32 get();
quint32 write(quint32 *pSrc, quint32 uCount);
quint32 read(quint32 *pDest, quint32 uCount);

private:
quint32 m_uLevel;
quint32 m_uDepth;
quint32 *m_pR;
quint32 *m_pW;
quint32 *m_pBuffer;
};

#endif

Rambobino
10th August 2010, 20:56
Ok after further investigation it looks like the problem is in the put() and get() functions of the ring buffer class. When they are not called everything is fine.
Even if everything is on the stack, it crashes after using put() and get().

Rambobino
10th August 2010, 21:35
Ok forget about my post, I found the problem...

The buffer always had a size of 0 because i was using the wrong variable to create it..


void CRingBuffer32::initialize(quint32 uDepth)
{
m_uLevel = 0;
m_uDepth = uDepth;

if(m_pBuffer)
{
delete[] m_pBuffer;
}

m_pBuffer = new quint32[m_uDepth]; // <-- was using m_uLevel here...

m_pR = m_pBuffer;
m_pW = m_pBuffer;
}