2017-01-31 4 views
-3

申し訳ありませんが、悪いタイトルでは、私はちょうどメモリリークがそれぞれ私のプログラムでいくつかの悪いことをしたと言うことができます。Microsoftのメモリリーク検出の意味を理解する

{1640} normal block at 0x081C2AB0, 4 bytes long. 
Data: <; > 3B 00 00 00 
{789} normal block at 0x08B792E8, 12 bytes long. 
Data: <   > 00 00 00 00 00 00 00 00 00 00 00 00 
{788} normal block at 0x027E62D8, 32 bytes long. 
Data: <   L L > 20 A8 FE 07 A0 A0 17 08 E4 4C F3 07 D8 4C F3 07 
{787} normal block at 0x027E6328, 32 bytes long. 
Data: <layer03 - Object> 6C 61 79 65 72 30 33 20 2D 20 4F 62 6A 65 63 74 
{786} normal block at 0x08B79748, 8 bytes long. 
Data: <`N  > 60 4E F3 07 00 00 00 00 

私は本当に理解することはできません:私は、Visual Studio(_CrtDumpMemoryLeaks())でメモリリークテストを実行してきたし、それが(ちょうど小さな部分を示す)、検出漏れの巨大なリストを出力

私が間違ってやったのは何か。私はanother question of mineからのtippsに続き、スマートポインタ(または少なくとも私がやったと思う)ですべてnew/deleteものを置き換えました。

私が尋ねる理由は、自分のプログラムを実行しているときにメモリサイズとヒープサイズが増加しているため、重大な問題か基本的な振る舞いであるかどうかわからないからです。

は、例えば、私の(自作)GUIください:

std::shared_ptr<Gui_Button> gui_modal_window_map_saved_button; 

をそして私は今でそれを呼び出す:

メモリ安全であると言われている
gui_modal_window_map_saved_button.reset(new Gui_Button(res_handler, "Select", 20, 345, 70, 40, BUTTON_CONFIRM)); 

。今、本当にわからないことがあります。どうすればこのボタンを安全に削除できますか?私は知っている、スマートポインタでの削除のようなものは何もないが、私は、ボタンが不要になったとき、つまり対応するウィンドウが閉じられた後にボタンを削除する方法で削除することを考えている。毎回「新しい」ボタンを瞬間

は、私は、これは大丈夫だと思ったreset()

if (g_ev.event_id == EVENT_CLICKED && g_ev.element == gui_modal_window_map_saved_button.get()) { 
     gui_modal_window_map_saved.reset(); 
     gui_modal_window_map_saved_button.reset(); 
    } 

と私のボタンを「削除」していますが、なぜ私のメモリサイズは増加している(と再び減少していません)創造された?

バック私は、Visual Studioでのメモリリークのこれらのダンプを取得し、元の質問

に来て、私は本当にこの情報を使用する方法を見つけ出すことはできません。正確にメモリリークの原因は何ですか?私は現在、別のクラスに何かを渡す必要のある「通常の」ポインタだけを使用しています。new/deletesをスマートポインタで置き換えました。私は実際には約3000行までですので、私のコードを表示することはできません。

それでは、正確にどのようにメモリリークが発生し、どのようにVSが提供する情報を使用しますか?

+0

これは一般的な質問ですか? – elasticman

+0

ノートパソコンを雨の中に置かない限り、メモリリークはハードウェアに関するものではありません。 –

+0

グレーエリア。私はメモリリークが一般的な質問だと言うでしょう。 –

答えて

0

Microsoftは見ているデータを利用する方法についての詳細な情報を提供していますhttps://msdn.microsoft.com/en-us/library/x98tx3cf.aspx

割り当てが行われた時点で、あなたのコードに分割する割り当て番号を使用することが可能です。デバッグ出力から次の行に:

{789} normal block at 0x08B792E8, 12 bytes long.

789割付け番号です。あなたは、メモリ使用量が増えていると言います。これは、セッションが長くなるとリークメッセージが増加しない限り、リークが拡大するとは限りません。

もう一つ考慮すべきことは、あなたのクラス内でリークが発生していることです。あなたのオブジェクトの中に適切に処理されていない要素があれば、スマートポインタはあなたを救うものではありません。

+0

"実行終了時にリーク記録が増えない場合は、漏れが増えていません。" - これ以上説明できますか?実行終了時にレコードをどのように測定するのですか? – elasticman

+0

それらを数えます。あなたがすぐに数えることができる以上のものがあれば、それが成長しているかどうかは関係ありません。あなたは十分な問題があります。 –

0

C++は、それがいわゆるガベージコレクタを持っていないことで、多くの新しい言語とは異なります。 newでメモリを割り当て(クレーム)、deleteで明示的に割り当てを解除(解放)します。

あなたがdeleteを忘れてしまった場合、あなたのプログラムが存在した後、メモリは、オペレーティングシステムによって解放されます。

deleteを使用してnewの使用を均衡させるには、可能であれば、コンストラクタにメモリを割り当て、(仮想)デストラクタでメモリを割り当て解除します。このようにして、ヒープメモリ(newで割り当てられたメモリ)を所有するオブジェクトが範囲外になると(例えば、関数を出るときにローカル変数)、メモリは自動的に解放されます。割り当てと、このようにメモリを割り当て解除ところで

は、C++の汎用性とスピードを与えるものの一つです。したがって、避けるべきものではなく、資産です。しかし、慎重に使用する必要があります。

+0

はい、それは私が学んだことです。しかし、もし私が明示的に新しいものを呼び出さなければ、私は問題を起こすべきではありません。 – elasticman

+0

確かに、あなたはすべきではありません。 –

+1

他のいくつかの答えで私は_CrtDumpMemoryLeaks()を呼び出す可能性があることを読みました。不適切な場所で現在、私はプログラムの最後の前に置いています(return 0の前に) – elasticman

関連する問題