2011-07-02 29 views
1

メモリの割り当てにもう一度問題があり、その理由を理解できません。メモリ割り当て/ std :: stringコンストラクタでのヒープの破損

私はデバッグモードでプログラムを実行すると、私は(私はできるだけ正確にそれを翻訳してみました)次のエラーメッセージを受け取る:

WindowsはLogoColorDetector.exeにブレークポイントをトリガしました。私は問題は次の行で発生しているようだことがわかったプログラムをデバッグする場合これは、ヒープLogoColorDetector.exeに問題があることを示して破損やそのロードされたDLLの1 [...]

によって発生する可能性があります。

imgTrain [J]の画像オブジェクトが正しい_filePath文字列を持っている場合、私はすでに確認されている

const std::string& support::Image::getFilepath() const 
{ 
    return this->_filePath; 
} 

: -

std::string tmp = imgTrain2[j]->getFilepath(); 

getFilepath()次のように機能が実装されています。だから問題はどこか別のものだと思う。面白いことは、問題のある行を含む関数がうまくいくようだということです。関数が呼び出されるのは2回目ですが、関数自体に問題がないことが示されます。私は、任意のメモリを割り当てません。また私は、それがスタックトレースここでは誰のためのヘルプ、あるかもしれない場合はstd ::文字列

を介して間接的に行われているものを除き、関数内で何も削除します:

msvcr100d.dll!_heap_alloc_base(unsigned int size) Zeile 55 C 
msvcr100d.dll!_heap_alloc_dbg_impl(unsigned int nSize, int nBlockUse, const char * szFileName, int nLine, int * errno_tmp) Zeile 431 + 0x9 Bytes C++ 
msvcr100d.dll!_nh_malloc_dbg_impl(unsigned int nSize, int nhFlag, int nBlockUse, const char * szFileName, int nLine, int * errno_tmp) Zeile 239 + 0x19 Bytes C++ 
msvcr100d.dll!_nh_malloc_dbg(unsigned int nSize, int nhFlag, int nBlockUse, const char * szFileName, int nLine) Zeile 302 + 0x1d Bytes C++ 
msvcr100d.dll!malloc(unsigned int nSize) Zeile 56 + 0x15 Bytes C++ 
msvcr100d.dll!operator new(unsigned int size) Zeile 59 + 0x9 Bytes C++ 
LogoColorDetector.exe!std::_Allocate<char>(unsigned int _Count, char * __formal) Zeile 36 + 0xf Bytes C++ 
LogoColorDetector.exe!std::allocator<char>::allocate(unsigned int _Count) Zeile 187 + 0xb Bytes C++ 
LogoColorDetector.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Copy(unsigned int _Newsize, unsigned int _Oldlen) Zeile 1933 + 0x12 Bytes C++ 
LogoColorDetector.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Grow(unsigned int _Newsize, bool _Trim) Zeile 1963 + 0x13 Bytes C++ 
LogoColorDetector.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::assign(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & _Right, unsigned int _Roff, unsigned int _Count) Zeile 902 + 0xe Bytes C++ 
LogoColorDetector.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> >(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & _Right) Zeile 546 C++ 
LogoColorDetector.exe!compareClasses(support::ImageCollection * coll, support::ImageClass * cl1, support::ImageClass * cl2, float * mean, float * var) Zeile 111 + 0x22 Bytes C++ 

これを引き起こす可能性のある人は誰ですか?

ありがとうございました。

- 編集 -

は、Visualリークディテクタとの提案をしようとしました。上記のエラーメッセージがポップアップし、メモリが解放された後にメモリが変更されたという瞬間までは、何も表示されません。どのオブジェクトがメモリアドレスに関連付けられているかを調べる方法はありますか?メモリダンプはあまり役に立ちません。

物事をよりmyterious作るために、私は次の行を追加してみました:今、最初の行が正しく実行され、2行目に障害が発生した

std::string tmp = imgTrain2[j]->getFilepath(); 
std::string t2Path = imgTrain2[j]->getFilepath(); 

を。

+0

参照の代わりにコピーを返すgetFilepath()はどうでしょうか? 'const std :: string support :: Image :: getFilepath()const' – karlphillip

答えて

9

実行時にヒープの破損が検出されると、ヒープはであり、すでにが破損しています。これは、以前の操作でそれが乱れたことを意味します(例:配列の範囲を超えて何かを書いた、ポインタが壊れているなど)。

ビジュアルリークディテクタや、使用してはいけないメモリ位置を上書きする正確なポイントでエラーが発生する可能性のあるツールを使用してプログラムを実行します(注:これでもコードにエラーが表示されない場合があります以前にポインタを破損していたとしても、少なくともの場合はが壊れています)。

更新:デビッドの答えにはいくつかの補遺は

はアナロジーを終了するには(申し訳ありませんが、SO長いコメントを許可していません):あなたのプログラムにバグがあります。バグを含む行が実行されると、エラーが発生する可能性があります。割り当てられたメモリチャンクに関する情報を格納するヒープの一部を上書きします。ランタイムはこれを認識せず、そのメモリセグメントはプロセスに属しているため、書き込むことができるはずです。失敗しません。新しいメモリを割り当てようとすると、新しい演算子はheap_alloc_を呼び出して新しいメモリチャンクを取得します。 allocのコードは、割り当てられたメモリチャンクのチェーンを通り抜け、そこにいくらかのゴミを発見します。本当に悪いことが起こっていることを知らせることができません。これでエラーを引き起こしたコードのバグを見つけなければなりません。いくつかのツールがなければ、コード全体をチェックしてバグを確認する必要があります。

+0

+1とても良い説明です。 – Josh

3

ヒープをゴミ箱に移動すると、ソースとエラーの検出が場所と時間で大きく分けられます。障害、エラー、および障害には大きな違いがあります。

偶然のように、ゼロになっていたが、何らかの理由で1つの状態で永続的にスタックされていたメモリのビットを考えてみましょう。これは誤りです。まだ影響はありません。ビットの次の操作がそれをオンにすることであるとします。この命令は、この誤りを隠していた。ある意味では問題は存在しません。読者は1つの値、正しい値を受け取ります。それをゼロにすると、障害は再び真ですが、これは問題ではありません。ビットがゼロでなければならないときに読者が1つを読むまで、問題は現れません。この時点で、障害によってエラーが発生しました。これはまだ問題ではないかもしれません。エラーは、失敗したビットがpiの格納された値の仮数の最下位ビットであった場合に影響を与えないことがある。いくつかのビット障害は問題を引き起こす。間違ったビットの失敗は、例えば、宇宙飛行士が聴覚障害者になってしまう(実際には行った)かもしれない。エラーによりシステムが何らかの形で重大な動作をすると、エラーが発生します。

あなたのコードは、行のどこかに割り当てられたメモリの一部で少しダンスをしました。それは欠陥だった。ダンスされたメモリにアクセスしようとするまで、あなたのコードは気楽に実行されました:エラー。これらのエラーのいくつかはおそらく良性だったでしょう。あなたのプログラムは、ダンス・オン・メモリを介してアクセスしようとする可能性が最も高いクリティカルなコードになるまで、気楽に続きました。

私はあなたがimgTrain2[j]に書き込んだ行のどこかにいると思われます。今あなたは悪いポインタを持っています。

+0

'imgTrain2 [j]'はおそらく問題ありません。そして、それが悪い場合でも、このエラーメッセージが表示されません。ヒープが破損しています。ニースの書き込み、しかし:) –

関連する問題