4

単純なsynchronizedQueueがあります

 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
};

キューからデキューすると、ヒープが破損することがあります。

HEAP:解放された後にccb13c0で変更された解放ヒープブロックccb1080

コールスタックは:

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() 

このヒープの破損の原因は何ですか?ヒープ破損エラーをデバッグする方法は?何か案は...

更新: 使用例

// 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();

}
4

3 に答える 3

2

上記のように、コードと投稿したスタック トレースは、一部のメモリ割り当てが進行中であることを示しています。エラーメッセージとともに、ヒープの破損が別の場所で発生し、それらのベクトルをコピーするために大量のメモリを使用するため、デキューで毎回ポップアップするだけだと思います。

エラーを見つけるには、メモリ プロファイリング ツール (例: http://www.softwareverify.com/cpp-memory.php ) の評価版を使用します。市場には無料のツールもいくつかありますが (特に Valgrind)、Visual C++ に適した無料のツールは知りません。

さらに、この投稿を確認できますヒープ破損エラーをデバッグする方法? このエラーに対処する方法に関する追加の方法については、こちらをご覧ください。

私が今まで見てきたことから、エラーはあなたが投稿したコードにはありません。さらにヘルプが必要な場合は、エラーを含む小さな自己完結型の例を提供してください。


試してみる価値のある無料のツールを見つけました: Dr. Memory . もちろん、 stackoverflowからリンクを取得しました。

于 2012-08-15T13:05:58.497 に答える
1

はい、。ランタイム ライブラリのリリース バージョンとデバッグ バージョンを混在させている可能性があります。

Windows(AFAIKのみ)には2つの異なるランタイムライブラリがあり、リリースバージョンは予想どおりにメモリ割り当てを行いますが、デバッグバージョンはすべての割り当てにガードブロックを追加するため、バッファオーバーフローやその他のメモリエラーを追跡できます. このシステムの問題は、同じアプリケーションで Release ライブラリと Debug ライブラリを混在させると、(たとえば) Release で 10 バイトを割り当て、次に Debug で 18 バイト (4+10+4) を解放することです。

トリックは、すべてのデバッグまたはすべてのリリースを毎回ビルドしてリンクすることです。または、デバッグ ビルドでリリース ライブラリを使用する必要がある場合は、dll で行われたすべての割り当ても同じライブラリによって解放されるようにする必要があります。CRT の新規/削除ルーチンの使用を許可しないでください。関数。これにより、dll A の 10 バイトの割り当てが同じ dll によって確実に解放され、明らかに 10 バイトのみが削除されます。

編集:

そうでない場合は、コピー コンストラクター (デキューの 32 行目) を使用して新しいベクターを割り当てるときに、コール スタックを見るとエラーが表示されるので、最初にその行を 2 つのステートメントに分割して、それがコピーかどうかを確認するか、または問題の原因となっているポップ (どの行が問題なのかを確実に把握するために、ポップの間にデバッグ ステートメントを入れる傾向があります)。

あなたのサンプルコードは、キューにアクセスする2つの異なる方法を示しています-> Enqueueと.Dequeueは、キュー自体の複雑さを示唆しています。

于 2012-08-15T10:39:05.790 に答える
0

これらは、デバッグ ビルドでヒープが破損していないことを確認するために呼び出す非常に便利な関数です。

_ASSERTE( _CrtCheckMemory( ) );

フラグを設定して、終了時にメモリ リークをチェックすることもできます。

次のフラグを設定 (OR) することにより: _CRTDBG_LEAK_CHECK_DF

詳細については、次のページを参照してください。

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

于 2013-07-19T20:20:00.973 に答える