メモリリークについて教えてください。
最近VC++を勉強中なのですが、メモリリークというものを知り、_CrtDumpMemoryLeaks()をしたところ、以下のコメントが出力されました。
[コメント]
Detected memory leaks!
Dumping objects ->
strcore.cpp(118) : {71} normal block at 0x00344978, 20 bytes long.
Data: < cmd.> 01 00 00 00 07 00 00 00 07 00 00 00 63 6D 64 2E
{48} client block at 0x003428E8, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $003428E8, 64 bytes long
{43} client block at 0x00342720, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $00342720, 64 bytes long
{41} client block at 0x003425D0, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $003425D0, 64 bytes long
Object dump complete.
スレッド 0x584 終了、終了コード 0 (0x0)。
上記のコメントから、メモリリークを起こしていることはわかりました。ただ、strcore.cppというクラスは作成していないのですが、エラーが出ます。
多分他の関数から呼ばれているクラスだと思うため、クラス等をコメントアウトして調べたのですが、エラーがまだ出力されます。
(Data: < cmd.> 01 00 00 00 07 00 00 00 07 00 00 00 63 6D 64 2Eここは自作クラス上の問題だと思います。)
newとかの解放はしているのですが、他にメモリリークをする原因ってあるのでしょうか?
No.1
- 回答日時:
>ただ、strcore.cppというクラスは作成していないのですが、エラーが出ます。
.cppって位だからソースでしょ(^^;;;
で、(118)が行番号。
MFCのソースはインストールしてますか?
VC++6.0SP6だと、該当行はCString::AllocBuffer()でした。
>newとかの解放はしているのですが、他にメモリリークをする原因ってあるのでしょうか?
ちゃんと解放していないとか。
こんなソースだとリークします。
CString pstr* = new CString[2];
delete pstr;
あとは、MFC等のフレームワークを使っているのであれば、その内部。
メモリリークとは、何度も確保されても解放されずに使用量が増えていくのがまずいのであって、該当個所では1度だけ確保して終了時まで保持しておくという使い方であれば、まずくはありません。(気持ち悪い気もしますが)
この回答への補足
ありがとうございます。
原因の個所がわかりました。
[ソース] 一部抜粋
CString mstrCmdLine;
mstrCmdLine = "cmd.exe";
char *cl = new char[mstrCmdLine.GetLength() + 1];
strcpy(cl,mstrCmdLine);
nResult = CreateProcess(NULL,cl,NULL,NULL,FALSE,0,NULL,NULL,&str_inf,&pro_id);
delete[] cl;
CStringからLPTSTR型に変換をすると、CreateProcessでエラーが発生します。(cl)
直接clの部分を"cmd.exe"に直接記述するとメモリリークは起こさないみたいなので、char* への変換が間違っているのですか?
だとするとCStringからchar*への変換は良くないのでしょうか?
直接変数を LPTSTR型で領域を確保したほうがよろしいのですか?
例 LPTSTR mstrCmdLine;
mstrCmdLine = "cmd.exe";
nResult = CreateProcess(NULL,mstrCmdLine,NULL,NULL,FALSE,0,NULL,NULL,&str_inf,&pro_id);
No.2
- 回答日時:
ヘルプより:
>lpCommandLine
>実行するべきコマンドラインを保持している、NULL で終わる文字列へのポインタを指定します。
>システムはこのコマンドラインの最後に NULL を追加し、必要に応じて文字列を切り捨て、
>実際にどのファイルを使うのか指定します。
なんで、
>char *cl = new char[mstrCmdLine.GetLength() + 1];
足りてません。1ではなく2足してください。
>例 LPTSTR mstrCmdLine;
>mstrCmdLine = "cmd.exe";
これってキャストしないでコンパイル通りますか?
この回答への補足
たびたびご回答ありがとうございます。
OS windows2000
visual c++ 6.0 を使用しています。
■1
>char *cl = new char[mstrCmdLine.GetLength() + 2];
にしましたが、以前と変わらずエラーが出ました。
もっと調べないとだめですね(^^;
納得いかないですね。
■2
>例 LPTSTR mstrCmdLine;
>mstrCmdLine = "cmd.exe";
>これってキャストしないでコンパイル通りますか?
class xxx : CObject
private:
LPTSTR mstrCmdLine;
:
:
}
int xxx::xxxx(){
mstrCmdLine = "cmd.exe";
:
:
:
}
でやったらコンパイル通りました。
今考えると可笑しいですね。?(^^;?
No.3
- 回答日時:
-----
PROCESS_INFORMATION pro_id;
STARTUPINFO str_inf;
::ZeroMemory(&str_inf, sizeof(str_inf));
str_inf.cb = sizeof(str_inf);
str_inf.dwFlags = STARTF_USESHOWWINDOW;
str_inf.wShowWindow = SW_SHOW;
CString mstrCmdLine;
mstrCmdLine = "cmd.exe";
char *cl = new char[mstrCmdLine.GetLength() + 2];
strcpy(cl,mstrCmdLine);
CreateProcess(NULL,cl,NULL,NULL,FALSE,0,NULL,NULL,&str_inf,&pro_id);
delete[] cl;
-----
というコードを実行してみましたが、メモリリークは発生しませんでした。
ですので、原因はまだ明かされていないコードのどこかにあるのではないかと思います。
_CrtDumpMemoryLeaksにおいてメモリリークが検出された場合、一番最後に表示されたメモリリークに問題がある場合が多いです。
下から順番に解決していきましょう。
{41} client block at 0x003425D0, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $003425D0, 64 bytes long
最初に解析するのはこれです。
このメモリリークの原因はもう解決しましたか?
●このメモリリークの原因探しに難航している場合
プログラムの先頭の方に
_CrtSetBreakAlloc(41);
というコードを追加し、デバッグモードで実行してみましょう。
うまく行けば、メモリリークを起こしているオブジェクトを生成しているところで停止してくれます。
停止したら、そのオブジェクトが本当に解放されているのか確認してみて下さい。
●残りはもうstrcore.cppで発生しているメモリリークだけの場合
strcore.cpp(118) : {71} normal block at 0x00344978, 20 bytes long.
Data: < cmd.> 01 00 00 00 07 00 00 00 07 00 00 00 63 6D 64 2E
となっていますので、
プログラムの先頭の方に
_CrtSetBreakAlloc(71);
というコードを追加し、デバッグモードで実行してみましょう。
うまく行けば、メモリリークを起こしているオブジェクトを生成しているところで停止してくれます。
停止したら、そのオブジェクトが本当に解放されているのか確認してみて下さい。
ただしどちらの方法も起動するたびに{}の中の数字が変わるような状況では役に立ちません。ご注意下さい。
この回答への補足
ありがとうございます。
大変勉強になります。
まず、新規にVC6++を立ち上げ(MFC(exe)→ダイアログ)、以下のソースを入力したところ同じメモリリークになりました。(提供されたソースをコピーしました)
[ソース]
void CMy2Dlg::OnOK()
{
// TODO: この位置にその他の検証用のコードを追加してください
_CrtSetBreakAlloc(71);
PROCESS_INFORMATION pro_id;
STARTUPINFO str_inf;
::ZeroMemory(&str_inf, sizeof(str_inf));
str_inf.cb = sizeof(str_inf);
str_inf.dwFlags = STARTF_USESHOWWINDOW;
str_inf.wShowWindow = SW_SHOW;
CString mstrCmdLine;
mstrCmdLine = "cmd.exe";
char *cl = new char[mstrCmdLine.GetLength() + 2];
strcpy(cl,mstrCmdLine);
CreateProcess(NULL,cl,NULL,NULL,FALSE,0,NULL,NULL,&str_inf,&pro_id);
delete[] cl;
CDialog::OnOK();
_CrtDumpMemoryLeaks();
}
ですが、
Detected memory leaks!
Dumping objects ->
strcore.cpp(118) : {71} normal block at 0x00344908, 20 bytes long.
Data: < cmd.> 01 00 00 00 07 00 00 00 07 00 00 00 63 6D 64 2E
{48} client block at 0x003428E8, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $003428E8, 64 bytes long
{43} client block at 0x00342720, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $00342720, 64 bytes long
{41} client block at 0x003425D0, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $003425D0, 64 bytes long
Object dump complete.
スレッド 0x6C4 終了、終了コード 0 (0x0)。
の同じ結果が返ってきます。
PCか、vc++か、記述に問題があるのか・・・
因みに、教えていただきました_CrtSetBreakAllocですが41、43、48でブレークはしませんでした。
71でブレークし見ると、
---------------------------
/* break into debugger at specific memory allocation */
if (lRequest == _crtBreakAlloc)
_CrtDbgBreak(); < ---- ここでとまっている。
---------------------------
そのままF10(Nextコンパイル)で見ていくと、
char *cl = new char[mstrCmdLine.GetLength() + 2];
に戻ってきます。
何か設定していないことがあるのか??
No.4
- 回答日時:
>PCか、vc++か、記述に問題があるのか・・・
記述というか確認方法ですかね。
_CrtDumpMemoryLeaks()を呼ぶタイミングが早すぎます。ローカル変数のデストラクタが呼ばれていません。
中括弧で処理を囲って、その前後でメモリリーク調査の関数を呼んでください。
もしくは調査対象の処理を別関数にするか。
void CMy2Dlg::OnOK()
{
// TODO: この位置にその他の検証用のコードを追加してください
_CrtSetBreakAlloc(71);
{ //追加
PROCESS_INFORMATION pro_id;
STARTUPINFO str_inf;
::ZeroMemory(&str_inf, sizeof(str_inf));
str_inf.cb = sizeof(str_inf);
str_inf.dwFlags = STARTF_USESHOWWINDOW;
str_inf.wShowWindow = SW_SHOW;
CString mstrCmdLine;
mstrCmdLine = "cmd.exe";
char *cl = new char[mstrCmdLine.GetLength() + 2];
strcpy(cl,mstrCmdLine);
CreateProcess(NULL,cl,NULL,NULL,FALSE,0,NULL,NULL,&str_inf,&pro_id);
delete[] cl;
CDialog::OnOK();
} //追加
_CrtDumpMemoryLeaks();
}
この回答への補足
いつもありがとうございます。
[ソース]
void CMy2Dlg::OnOK()
{
_CrtSetBreakAlloc(71);
{
// TODO: この位置にその他の検証用のコードを追加してください。
PROCESS_INFORMATION pro_id;
STARTUPINFO str_inf;
::ZeroMemory(&str_inf,sizeof(str_inf));
str_inf.cb = sizeof(str_inf);
str_inf.dwFlags = STARTF_USESHOWWINDOW;
str_inf.wShowWindow = SW_SHOW;
CString mstrCmdLine;
mstrCmdLine = "cmd.exe";
char *cl = new char[mstrCmdLine.GetLength() + 2];
strcpy(cl,mstrCmdLine);
CreateProcess(NULL,cl,NULL,NULL,FALSE,0,NULL,NULL,&str_inf,&pro_id);
delete[] cl;
CloseHandle(pro_id.hProcess);
CDialog::OnOK();
}
_CrtDumpMemoryLeaks();
}
以上のように記述したら、以下のような結果になりました。
umping objects ->
{48} client block at 0x003428E8, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $003428E8, 64 bytes long
{43} client block at 0x00342720, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $00342720, 64 bytes long
{41} client block at 0x003425D0, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $003425D0, 64 bytes long
Object dump complete.
スレッド 0x790 終了、終了コード 0 (0x0)。
プログラム 'D:\work\1.docomo\作業\20050114 ファイルコピー\test\2\Debug\2.exe' はコード 0 (0x0) で終了しました。
一様CString系のメモリリークはなくなりました。
他のは調べていますが、よくわかりません。
問題ないようにも思えますが・・・
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
あなたが普段思っている「これまだ誰も言ってなかったけど共感されるだろうな」というあるあるを教えてください
-
フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
あなたが普段思っている「これまだ誰も言ってなかったけど共感されるだろうな」というあるあるを教えてください
-
映画のエンドロール観る派?観ない派?
映画が終わった後、すぐに席を立って帰る方もちらほら見かけます。皆さんはエンドロールの最後まで観ていきますか?
-
海外旅行から帰ってきたら、まず何を食べる?
帰国して1番食べたくなるもの、食べたくなるだろうなと思うもの、皆さんはありますか?
-
天使と悪魔選手権
悪魔がこんなささやきをしていたら、天使のあなたはなんと言って止めますか?
-
Detected memory leaks!
C言語・C++・C#
-
VC++ オリジナルDLLを使用するとアプリを終了させる時にメモリリークする
C言語・C++・C#
-
画面を強制的に再描画させる方法
C言語・C++・C#
-
-
4
「fatal error C1189」を回避するには?
C言語・C++・C#
-
5
charからLPTSTRへの変換方法
C言語・C++・C#
-
6
CStringの文字列検索&抜き出しについて
C言語・C++・C#
-
7
EDITコントロールで入力できる文字を制限するには?
C言語・C++・C#
-
8
ダイアログボックスのボタンコントロールのフォーカスについて
C言語・C++・C#
-
9
CString から LPCTSTRの型に変換
C言語・C++・C#
-
10
テキストボックスからフォーカス外す
C言語・C++・C#
-
11
MFC、ダイアログベースでのモードレス作成
C言語・C++・C#
-
12
char型配列の最大要素数
C言語・C++・C#
-
13
CStringからchar*への型変換について教えてください。
C言語・C++・C#
-
14
char str[256]の256の意味は?
C言語・C++・C#
-
15
コンボボックス表示文字列を取得する場合
C言語・C++・C#
-
16
(マルチスレッド)_beginthreadexに複数の引数を渡す
C言語・C++・C#
-
17
deleteで開放するとエラーになる原因がわからない
C言語・C++・C#
-
18
CStringのFindで文字列検索を行いたいのですが
C言語・C++・C#
-
19
VC++スレッドの正しい終了のさせかた
C言語・C++・C#
-
20
構文エラー;"が型の前にありませんとは、どうしたら解決できるのですか。"
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C#でログファイルにファイルパ...
-
c言語
-
大量のデータを読み込んで表示...
-
gccを行ってもexeファイルが生...
-
UART通信の取説で,left floati...
-
PC画面を録画するプログラムでd...
-
C言語について。
-
Windows Formアプリからコンソ...
-
プログラムを斜めに並べる
-
今ってプログラミング言語は何...
-
コンソールアプリを作成するの...
-
【C言語】全角文字の配列を、全...
-
C# DatagridviewにExcelシート...
-
逆コンパイルと逆アセンブルの...
-
プログラムの実行時に'<'でリダ...
-
バッチファイルで以下のような...
-
インクリメント演算子のみを用...
-
mallocについて
-
システムエンジニアの適正について
-
どちのほうがすきですか?
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
どうして+3
-
プログラミング言語についてc++...
-
今ってプログラミング言語は何...
-
2つほどお聞きしたいことがあり...
-
次の記述について
-
パソコン
-
バッチファイルで以下のような...
-
大量のデータを読み込んで表示...
-
c言語
-
Windows Formアプリからコンソ...
-
gccを行ってもexeファイルが生...
-
VisualStudio2022でC言語プログ...
-
UART通信の取説で,left floati...
-
C#でTreeViewのCheckBoxのサイ...
-
10進数からN進数に変換するプロ...
-
Python、プログラミングについ...
-
[C言語]fputsとfprintfの違い
-
0 == False はいいけど
-
VisualStudioで、コードを印刷...
-
逆コンパイルと逆アセンブルの...
おすすめ情報