• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:メモリーリークの検出について)

メモリーリークの検出方法

このQ&Aのポイント
  • WindowsXP,VC++6.0環境においてメモリーリークを検出する方法について調査しました。
  • _CrtSetDbgFlagを使用してメモリーリークを検出しようとしたが、正確なファイル名が表示されない問題が発生しました。
  • 短いコードでは正しく表示されるため、他の原因を考える必要があります。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

こんばんは。一応VC++6.0にて確認は出来たので以下サンプルを。 +--------------------test.hpp-----------------------+ #ifndef __TEST_HPP__ #define __TEST_HPP__ #include<cstdlib> #include<new> #include<memory> using namespace std; #include <crtdbg.h> #define _CRTDBG_MAP_ALLOC #define new ::new(_NORMAL_BLOCK, __FILE__, __LINE__) extern void TestB(); #endif +--------------------test.hpp-----------------------+ +--------------------testA.cpp----------------------+ #include"test.hpp" void TestA() { new int; _CrtDumpMemoryLeaks(); } int main() { ::TestA(); ::TestB(); return 0; } +--------------------testA.cpp----------------------+ +--------------------testB.cpp----------------------+ #include"test.hpp" void TestB() { new int; _CrtDumpMemoryLeaks(); } +--------------------testB.cpp----------------------+

box-box
質問者

お礼

回答ありがとうございます. 無事解決しました. お恥ずかしながら原因は,メモリーリーク検出初期設定をmain関数のあるソースでしか行っていなかったためでした. 本当にありがとうございました(^-^;)

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • アドレスの代入禁止方法

    宜しくお願いします。 私が考えている設計の、あるオブジェクトは生成されるインスタンスがプロジェクト内で単一であるとするものなので、アドレスの代入を禁止にしたいのです。 この場合はアドレスの代入禁止を目的としているので、メモリリークが発生していますがスマートポインタ等のメモリ管理法は使用しません。 operator=にてアドレスの代入禁止、もしくは別の方法がありましたら教えて頂けませんでしょうか。 以下はネット等を参考にしたソースコードです。 #include <crtdbg.h> class CHoge { public: CHoge(){}; private: CHoge(const CHoge&){}; CHoge& operator=(const CHoge&); }; int main() { _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); // 具体的にはこのような場合を想定した時の為です CHoge *pHoge = new CHoge; CHoge hogeB; pHoge = &hogeB;//ここを禁止する方法がわかりません return 0; }

  • メモリリークの件

    メモリリークについて教えてください。 最近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とかの解放はしているのですが、他にメモリリークをする原因ってあるのでしょうか?

  • C++でConvertSidToStringSid関数を使うために、sddl.hを使用したい

    お世話になります。 現在C++ 6.0でソフトを作成しています。 その中でConvertSidToStringSid関数を使うために、sddl.hを使用したいのですが、下記のようなエラーが出ます。 -----------インクルード------------------ #include <stdlib.h> #pragma comment(lib,"netapi32.lib") //////////ここで定義しているつもりです。 #define _WIN32_WINNT 0x0500 #include <windows.h> #include <sddl.h> //////////ここで定義しているつもりです。 #include <tchar.h> #include <lmaccess.h> #include <lmapibuf.h> #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ----------デバックエラー J:\Del.cpp(17) : fatal error C1083: インクルード ファイルがオープンできません。'sddl.h': No such file or directory どのようにすればConvertSidToStringSid関数を使うために、sddl.hを使用できますでしょうか? 何卒よろしくお願いします。

  • C言語のプログラムのメモリリークに関して

    動的メモリ管理を用いて,キーボードからの入力を行単位で辞書順にソートして出力するプログラムで、メモリリークが有るため解消したいのですが、freeをどのように用いれば良いのかが分かりません。 動的メモリについての理解が不十分であるため、自分なりにfreeを用いてみるとプログラムが途中で止まってしまい、解消することができません。 以下のプログラムは、自分なりにfreeを用いた部分を除けば、ソート後の出力は正しく出力されます。(メモリリークは発生します。) アドバイス、間違いの指摘等していただければと思います。お願いします。 環境は、Windows XP Professional SP3 32bitでVisual C++ 2008 Expressを使用しています。 #include <stdio.h> #include <string.h> #include <crtdbg.h> #include <stdlib.h> #define MAXLINES 20000 // 最大行数 #define LINELENGTH 20 // 1行の最大文字数 /* 標準入力からの入力を,一行づつ動的に確保したメモリに格納し, そのアドレスを文字列へのポインタ配列に保存する. Ctrl+Zで入力を終了する. lines : 文字列へのポインタの配列 numMax : 最大の読み込み行数*/ int ReadLines(char *lines[], int numMax){ int cnt = 0; static char buf[LINELENGTH]; while (cnt < numMax && gets(buf)) { lines[cnt] = malloc(strlen(buf) + 1); if (lines[cnt] == NULL) { printf("Allocation error.\n"); break; } strcpy(lines[cnt], buf); cnt++; } return cnt; } /* ポインタ配列の指す文字列を標準出力に表示 lines : 文字列へのポインタの配列 num : 行数*/ void PrintLines(char *lines[], int num){ int i; for (i = 0;i < num;i++) printf("%s\n", lines[i]); } /* ポインタの配列を,辞書順にソート lines : 文字列へのポインタの配列 num : 行数*/ void Sort(char *lines[], int num){ int i,j; char temp[LINELENGTH]; for(i=0;i<num;i++){ for(j=num-1;j>i;j--){ if(strcmp(lines[j],lines[j-1])<0){ strcpy(temp,lines[j]); strcpy(lines[j],lines[j-1]); strcpy(lines[j-1],temp); } } } } int main(){ int cnt,i; static char *lines[MAXLINES]; cnt = ReadLines(lines, MAXLINES); printf("----- %d lines -----\n", cnt); Sort(lines, cnt); PrintLines(lines, cnt); /*自分なりにfreeを用いた部分*/ for(i=0;i<cnt;i++){ free(lines[i]); } //メモリリーク情報の表示 _CrtDumpMemoryLeaks(); return 0; }

  • _CrtCheckMemoryのエラーについて

    現在、あるプログラムのヒープ破壊と思われるエラーで悩んでおり、VC++のヒープチェック機能でデバッグしようとしています。 メイン開発ツールはMingwなのですが、AddressSanitizerなどが未実装のようなので、ヒープチェックのためだけにVisual Studio Communityを導入しました。 ちょっと摘み食いするだけのつもりでしたので、GNUMAKEをそのまま使ってコンパイルしているのですが、なぜかヒープ破壊の検出がうまくいかないようです。 期待しているのは、ヒープチェックのAssertでヒープ破壊のタイミングを見つけることです。 他のサイトの情報を見ると、Assertが引っかかったタイミングで、ちゃんとソースファイル名と行番号が表示されるはずなのですが、なぜか以下のような情報を吐くだけで、CrtCheckMemoryのソース?が挙げられるだけです。 Debug Assertion Failed! File: debug_heap.cpp Line: 280 Expression _CrtCheckMemory() 問題を切り分けるため、ヒープ破壊するだけの「CrtCheckMemory_TEST.c」をつくり、以下のコマンドでコンパイルしましたが、結果は同じでした。 "C:\Program Files\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" x86 cl.exe /DUNICODE /D_UNICODE /D_DEBUG /MTd /c /FoCrtCheckMemory_TEST.obj CrtCheckMemory_TEST.c cl.exe /D_DEBUG /MTd /FeCrtCheckMemory_TEST.exe CrtCheckMemory_TEST.obj 1つ目は、コマンドラインからコンパイルするための環境変数を設定するバッチファイルを起動しています。 2つめは、UNICODE指定とデバッグフラグを立てて、/MTd(これがチェックのためのライブラリだと思っています。)オプションでオブジェクトファイルを作っています。 3つめは実行ファイルを生成しています。 なにか、オプションの指定し忘れなどがあるのでしょうか。 どなたか、ご教授願います。 環境は、Win7 Home 32bit、visual studio community 2017、Mingw 以下に、問題のソースを載せておきます。 #include <tchar.h> #include <stdio.h> #include <locale.h> #if defined (_MSC_VER) && (_DEBUG) #define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> #endif int main(int argc, char **argv){ TCHAR *text; setlocale( LC_ALL, "Japanese" ); #if defined (_MSC_VER) && (_DEBUG) _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_ALWAYS_DF ); _tprintf( _T("_CrtSetDbgFlag()実行\n") ); #endif if(argc>1){ printf( "argv=%s\n", argv[0] ); } text = malloc(10); _tprintf( _T("メモリ破壊開始\n") ); text[-6] = 7; _tprintf( _T("メモリ破壊終了\n") ); _ASSERTE( _CrtCheckMemory( ) ); return 0; }

  • global変数をブロック内から参照したい

    可変長配列の可変長配列を飲み込んで 吐き出すコードです global変数 *st_memory こいつをブロック内から参照するには どない書けば良いのでしょうか 構造体とか他の関数から引っぱり出しても 何故にかSegmentation faultで弾かれます mallocとかgotoの処理は無視して下さい _________________________ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #define MAX 256 typedef enum{ SUCCESS, EOF_FILE, MEM_OVER }Add_List; char *st_memory = NULL; //global void free_buffer(void){ free(st_memory); st_memory = NULL; } Add_List add_char(const int ch,int *count){ static int buffer = 0; assert(buffer >= *count); if(buffer == *count){ st_memory = (char *)realloc(st_memory, (buffer + MAX) * sizeof(char)); if(st_memory == NULL)return MEM_OVER; buffer += MAX; }// END if st_memory[*count] = ch; (*count)++; return SUCCESS; } // END add_char(const int,int); Add_List read_line(FILE *fp,char **line){ int ch,used_line = 0; Add_List status = SUCCESS; while((ch = getc(fp)) != EOF){ if(ch == '¥n'){ status = add_char('¥0',&used_line); if(status != SUCCESS)goto FUNK_END; break; } // END if status = add_char(ch,&used_line);// MAIN if(status != SUCCESS)goto FUNK_END; }// END while if(ch == EOF){ if(used_line > 0){ status = add_char('¥0',&used_line); if(status != SUCCESS)goto FUNK_END; }else{ status = EOF_FILE; goto FUNK_END; } // END if } // END if line[0] = (char *)malloc(sizeof(char) * used_line); if(line[0] == NULL){ status = MEM_OVER; goto FUNK_END; } strcpy(line[0],st_memory);// MAIN FUNK_END: if(status != SUCCESS)free_buffer(); return status; }// END read_line(FILE *,char **); char ** add_line(char **text_file,char *mem_line, int *line_alloc_num,int *line_num){ assert(*line_alloc_num >= *line_num); if(*line_alloc_num == *line_num){ text_file = (char **)realloc(text_file, (*line_alloc_num + MAX) * sizeof(char)); if(text_file == NULL)exit(0); *line_alloc_num += MAX; } // END if text_file[*line_num] = mem_line; (*line_num)++; return text_file; } // END add_line(char **,char *,int *,int *); char ** read_file(FILE *fp,int *line_p){ char **text_file = NULL; int line_alloc_num = 0; int line_num = 0; char *mem_line = NULL; while(read_line(fp,&mem_line) == 0){ text_file = add_line(text_file, mem_line,&line_alloc_num,&line_num); } // END while text_file = (char **)realloc(text_file, line_alloc_num * sizeof(char)); if(text_file == NULL)exit(0); *line_p = line_num; return text_file; } // END read_file((FILE *,int *); int main(void){ char **text = NULL; int i,line_num = 0; text = read_file(stdin,&line_num); printf("¥n"); for(i=0;i<line_num;i++) printf("%s¥n",text[i]); return 0; } ______________________

  • C++ vector中のnewしたの文字列の削除の問題

    C++の新人ですが、困っている質問をさせていただきます。 C++のvectorの中にchar型の文字列を格納していて、どうやって、 memory leak が発生しないようにクリアしますか? たとえば、以下の例 std::vector<char *> vc; void pushvc(); int main(){ pushvc(); } void pushvc(){ char* a = new char[10]; char* b = new char[10]; a="sss"; b="bbb"; vc.push_back(a); vc.push_back(b); } よろしくお願いします。

  • ヘッダーファイルがインクルードされない(?)

    ダイアログ上のボタンをクリックすると指定されたテキストファイルをオープンし、 ファイルの内容をスペースで区切って格納するプログラムを http://oshiete1.goo.ne.jp/kotaeru.php3?q=474452 こちらを少し変えて作ったのですが、 コンパイル・デバッグを行なうと 'std' : 識別子がクラス名でも名前空間名でもありません。 'vector' : 定義されていない識別子です。 'ofstream' : 定義されていない識別子です。 と言ったようなエラーになってしまいます。 必要なヘッダーファイルはインクルードされているはずなのですが・・・。 この原因は何故でしょうか? /**********プログラムソース**********/ #include <iostream> #include <fstream> #include <string> #include <vector> #include <utility> #include "stdafx.h" #include "SCHEDULE.h" #include "SCHEDULEDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // ~中略~ void CSCHEDULEDlg::OnReq() {    typedef std::pair<std::string,std::string> item;    std::vector<item> participation;    std::ofstream file(dataFile.txt);    std::string line;    while ( std::getline(file,line) ) {      std::string::size_type pos = line.find(' ');      participation.push_back(item(line.substr(0,pos), line.substr(pos+1)));    }    for ( int i = 0; i < participation.size(); ++ i) {      std::cout << "result = " << participation[j] << "]\n";    } }

  • _dupenv_s関数でメモリリーク

    VC++2005のMFCにてアプリを作成しています。 環境変数「TEST_ENV」の値を「OFF」にあらかじめ設定し、 _dupenv_s()関数にて変数の値を読込むプログラムなのですが、 プログラムをデバッグモードで実行し出力欄を見ると、 「Detected memory leaks!」と表示され、 原因箇所を探ると、どうやら ============================================== char* pGetEnv; size_t len; _dupenv_s( &pGetEnv, &len, "TEST_ENV" );←ここ ============================================== にて発生しているようです。 MSDNによると、lenにはバッファ容量を指定とあるので、 原因として、lenに何も指定されておらず、リークが発生していると考え、 Webで方法を色々調べたのですが、どのサイトも同じような書き方で、 解決法が分かりません。 どなたかご存知の方おられましたら、ご教授お願い致します。 なお下記にメッセージログを記載します。 Detected memory leaks! Dumping objects -> {73} normal block at 0x003A7018, 4 bytes long. Data: <OFF > 4F 46 46 00

  • Smarty includeでテンプレートを読み込めない

    よろしくお願いします。 まずphpファイルから $smarty->display('111/body.tpl');(*111はディレクトリ名) を呼び出して、さらにbody.tplと同ディレクトリにあるcontents.tplを読み込もうとしています。 はじめのbody.tplは読み込むことができブラウザで表示されるのですが、contents.tplは読み込めず、 Warning: Smarty error: unable to read resource: "contents.tpl" in <絶対パス>/Smarty/Smarty.class.php on line 1095 のエラーが出てしまいます。 ちなみに/111/というディレクトリは、$template_dir以下、$template_dir/111/です。 {include file="contents.tpl"} {include file="file:contents.tpl"} {include file="絶対パス/contents.tpl"} {include file="file:絶対パス/contents.tpl"} など試しましたが、ダメでした。 知恵をお貸しください。よろしくお願いします。

    • ベストアンサー
    • PHP