简体   繁体   中英

C++ corruption of the heap

I have a simple synchronisedQueue

 template <typename T>

    class SynchronisedQueue
    {
    public:

        void Enqueue(const T& data)
        {
            boost::unique_lock<boost::mutex> lock(queueMutex);
            dataQueue.push(data);
            conditionVariable.notify_one();
        } 

        T Dequeue()
        {
            boost::unique_lock<boost::mutex> lock(queueMutex);

            while (dataQueue.size()==0) 
            {
                conditionVariable.wait(lock);
            }

            T result=dataQueue.front(); dataQueue.pop();
            return result;
        } 


    private:

    std::queue<T> dataQueue;                        // Use STL queue to store data
boost::mutex queueMutex;                        // The mutex to synchronise on
boost::condition_variable conditionVariable;    // The condition to wait for
};

When I Dequeue from queue, I sometimes get corruption of the heap....

HEAP: Free Heap block ccb1080 modified at ccb13c0 after it was freed

call stack is :

ntdll.dll!76fa5654()    
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll] 
ntdll.dll!76f6a554()    
ntdll.dll!76f35a70()    
ntdll.dll!76fa5eff()    
ntdll.dll!76f6a3ba()    
ntdll.dll!76f35a70()    
msvcr90d.dll!_heap_alloc_base(unsigned int size=1222)  Line 105 + 0x28 bytes    C
msvcr90d.dll!_heap_alloc_dbg_impl(unsigned int nSize=1186, int nBlockUse=1, const char * szFileName=0x00000000, int nLine=0, int * errno_tmp=0x1310ee18)  Line 427 + 0x9 bytes  C++
msvcr90d.dll!_nh_malloc_dbg_impl(unsigned int nSize=1186, int nhFlag=0, int nBlockUse=1, const char * szFileName=0x00000000, int nLine=0, int * errno_tmp=0x1310ee18)  Line 239 + 0x19 bytes    C++
msvcr90d.dll!_nh_malloc_dbg(unsigned int nSize=1186, int nhFlag=0, int nBlockUse=1, const char * szFileName=0x00000000, int nLine=0)  Line 296 + 0x1d bytes C++
msvcr90d.dll!malloc(unsigned int nSize=1186)  Line 56 + 0x15 bytes  C++
msvcr90d.dll!operator new(unsigned int size=1186)  Line 59 + 0x9 bytes  C++
x.ax!std::_Allocate<unsigned char>(unsigned int _Count=1186, unsigned char * __formal=0x00000000)  Line 43 + 0x9 bytes  C++
ax.ax!std::allocator<unsigned char>::allocate(unsigned int _Count=1186)  Line 145 + 0xb bytes   C++
ax.ax!std::vector<unsigned char,std::allocator<unsigned char> >::_Buy(unsigned int _Capacity=1186)  Line 1110 + 0xf bytes   C++
ax.ax!std::vector<unsigned char,std::allocator<unsigned char> >::vector<unsigned char,std::allocator<unsigned char> >(const std::vector<unsigned char,std::allocator<unsigned char> > & _Right=[1186](83 'S',50 '2',54 '6',67 'C',162 '¢',4 '',0,0,108 'l',0,0,0,2 '',64 '@',0,0,6 '',14 '',64 '@',0,35 '#',2 '',147 '“',76 'L',114 'r',53 '5',0,0,54 '6',79 'O',78 'N',4 '',0,0,0,0,54 '6',79 'O',78 'N',4 '',0,0,0,0,255 'ÿ',255 'ÿ',255 'ÿ',255 'ÿ',255 'ÿ',255 'ÿ',255 'ÿ',255 'ÿ',106 'j',4 '',0,0,0,0,0,1 '',65 'A',154 'š',3 '',1 '',176 '°',159 'Ÿ',255 'ÿ',240 'ğ',199 'Ç',...))  Line 501 + 0x11 bytes    C++
ax.ax!SynchronisedQueue<std::vector<unsigned char,std::allocator<unsigned char> > >::Dequeue()  Line 32 + 0xc bytes C++
ax.ax!PPin::FillBuffer(IMediaSample * pSample=0x0cadbea8)  Line 225 + 0x12 bytes    C++
ax.ax!PPin::DoBufferProcessingLoop()  Line 300 + 0x13 bytes C++
ax.ax!CSourceStream::ThreadProc()  + 0x13e bytes    
ax.ax!CAMThread::InitialThreadProc()  + 0x51 bytes  
kernel32.dll!753bed6c()     
ntdll.dll!76f4377b()    
ntdll.dll!76f4374e() 

What may cause this heap corruption? How to debug heap corruption errors? Any ideas...

UPDATE: Usage sample

// Enqueue
void GetVideoStreams( BYTE *pData)
{
 std::vector<BYTE> vecFrame(pData, pData + nLen/sizeof(pData[0]));
 IncomingFramesQueue.Enqueue(vecFrame);

}

//Dequeue
void ConsumeVideoStreams()
{

 vector<BYTE> data = IncomingFramesQueue.Dequeue();

}

As stated above - your code & the stack trace you posted shows that some memory allocation is ongoing. Together with the error message, I assume that the heap corruption happened somewhere else and just pops up every time in dequeue since it uses a lot of memory for copying those vectors.

Use the evaluation version of some memory profiling tool (eg http://www.softwareverify.com/cpp-memory.php ) to find the error. There are also some free tools on the market (most notably Valgrind) but I don't know any good one for Visual C++ that is for free.

Additionally, you can check this post How to debug heap corruption errors? here for additional methods on how to tackle this error.

From what I've seen until now, the error's not in the code you posted. If you want more help, provide a small self contained example with the error.


I just found a free tool that might be worth a try: Dr. Memory . I got the link from stackoverflow of course.

Yes,. chances are you're mixing the Release and Debug versions of the runtime library.

On Windows (only AFAIK) there are 2 different runtime libraries, the release version does memory allocs as you'd expect, but the debug one adds guard blocks around all allocations so it can track buffer overflows and other memory errors. The problem with this system is that if you mix a Release and a Debug library in the same application, you will allocate (say) 10 bytes in Release and then free 18 bytes (4+10+4) in Debug.

The trick is to build and link either all Debug or all Release, every time. Alternatively, if you must use a Release lib in a debug build, then you must ensure that all allocations made in a dll is also freed by that same library - do not allow the CRT new/delete routines to be used, wrap them in a function. this ensures that the 10 byte alloc in dll A will be freed by the same dll, which obviously will only delete the 10 bytes.

EDIT:

ok, if it's not that, then looking at the call stack shows the error when allocating a new vector using the copy constructor (line 32 of Dequeue), so firstly split that line into 2 statements so you can see if its the copy, or the pop that's causing the problem (I always tend to put a debug statement between them just to make really sure you know which line is the problem).

Your sample code shows 2 different ways of accessing the queue ->Enqueue and .Dequeue which suggests more complexity in the queue itself.

These are extremely helpful functions to call to verify that the heap is not corrupted in debug build:

_ASSERTE( _CrtCheckMemory( ) );

You can also set the flag so that you check for memory leaks on exit:

By setting (OR'ing) the following flag: _CRTDBG_LEAK_CHECK_DF

See the following pages for more info:

http://msdn.microsoft.com/en-us/library/e73x0s4b(v=vs.110).aspx http://msdn.microsoft.com/en-us/library/5at7yxcs.aspx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM