• ベストアンサー

C++のnewで確保したメモリーの解放の確認方法

C++で作成中のプログラムの一部で、長い文章も処理できるように、構造体とメモリーの動的確保を使用しています。 ただ、動的に確保したメモリーは自分で解放しなくてはならないのですが、プログラムが単純なうちは開放のミスを発見できますが、長くなるとバグで一部開放されない可能性も捨てきれません。 そのようなときに全て開放できたか確認する方法は無いのでしょうか? 開発環境につきましては、 OS WindowsXP HomeEdition コンパイラ BCC 言語 C++ コンソールアプリケーション struct string { char str[512]; struct string* nextstr;}; 簡単には、このような構造体を new で確保し、開放は、先頭から delete してますが、 構造体がこれより結構複雑なため、処理部が長くきちんと開放できているか自信が有りません。

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

  • ベストアンサー
  • furyfox
  • ベストアンサー率56% (58/103)
回答No.4

newやdeleteをdefineで括ってまとめて監視してはどうですか? extern int g_count; #define NEWOBJECT(T) new (T); g_count++ #define DELETEOBJECT(ptr) delete (ptr) ; g_count-- int g_count; //ここのstringは自分で定義した構造体 string *p = NEWOBJECT(string); DELETEOBJECT(p); printf("メモリ確保数=%d",g_count); のようにするとか、 リリース版の時は #define NEWOBJECT(T) new (T) #define DELETEOBJECT(ptr) delete (ptr) とすれば余計の処理も消えますし。

shirousa01
質問者

お礼

回答ありがとうございます。 この方法は実装が簡単そうなので、試してみようかと思います。

その他の回答 (7)

  • KoHal
  • ベストアンサー率60% (110/181)
回答No.8

他の方の回答にレスを付けるのは規約違反なのだそうで、これは一人言であります。これも規約違反か(苦笑。 C++においてはクラスも構造体も同じ物です。 structはCとの互換のため、「メンバがデフォルトでpublicなクラス」として定められています。 よって構造体をnewで生成するのもクラスをnewで生成するのも全く同じことです。 まぁ、質問者さんはご存知のことでしょうが、このサイトを閲覧する人の中には混乱してしまう方があるかもしれませんので。

回答No.7

#6 > new、deleteはクラスのインスタンスの動的生成、破棄のためであって、メモリの領域を動的に確保、解放するためのものではありませんので。 そんなバカな。

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.6

newとdeleteをオーバーライドして確保、解放をファイルなどに記録していく。 というか構造体の領域の確保にnewを使うべきかという時点で違うのではと。 new、deleteはクラスのインスタンスの動的生成、破棄のためであって、メモリの領域を動的に確保、解放するためのものではありませんので。使えはしますが。 malloc、realloc、free等を使うべきだと思いますが。

参考URL:
http://www.hcn.zaq.ne.jp/no-ji/reseach/20000514.htm
shirousa01
質問者

お礼

回答ありがとうございます。 最初はmallocも考えたのですが、mallocは非常に扱いが難しいため今回の場合はnewを使用しようと思います。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

可能ならガベージコレクターを使って, そもそも解放など考えなくていいようにするんでしょうけど.

shirousa01
質問者

お礼

回答ありがとうございます。 なるほどガベージコレクターですか、 有用な方法ですね。 今後の開発時の手段の一つとして、覚えておきます。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.3

> 作成しているのがアプリケーションではなく、ある動作をするためのクラスなので、なるべく他のクラスや関数は使用しないで作ろうと思っているのです。 汎用的なクラスであっても、標準ライブラリを使わない理由は見当たらないと思います。組み込み用途ならそういうこともありますが、違うようですし。 > それに、メモリーの確保や開放を随時行わなくてはかなりのメモリを占有してしまうため、やはり、newとdeleteを使用するしかないのですが、 そういうことであれば、グローバルなnew/deleteではなく、専用のメモリプールを自作した方がよくありませんか?それなら、メモリリークの検出コードや、一括解放などの仕組みを付け加えることもできるはずです。 > 確保するデータ型は文字列(char配列)だけでなくさらに複雑なものもあり、扱うクラスが無いものもあるため、やはり確保と開放を確認しながら自分で作ったほうが安定します。 複雑な処理をnew/deleteでやっていると、メモリリークの対策だけでなく、例外安全性を維持するのも大変ではないですか?せめてstd::auto_ptrを使うぐらいのことはした方がよいと思います。

shirousa01
質問者

お礼

回答ありがとうございます。 たしかに、標準ライブラリは使用してもたいした問題は無いですね。 有用な標準ライブラリは使おうと思います。

  • t_nojiri
  • ベストアンサー率28% (595/2071)
回答No.2

メモリが開放されてるのかどうかなら、spy、パフォーマンスモニタ等のツールもしくは、何かデバッガ関係使うのが良いような気はします。 マルチプログラミング等なら、スレッド単位でデバッグしないとなりませんが。

shirousa01
質問者

補足

spyとは何でしょうか? gooで検索したらいろいろ引っかかって絞込みが不可能でした。 パフォーマンスモニタや、デバッガは、使いやすいのがなかなか見つからない故に現在使用していません。 なにか、使いやすいソフトがありましたら教えていただきたく思います。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

できれば、std::list<std::string>を使うなどして、メモリリークに悩まなくてもよい設計をした方がよいと思います。 もっと楽をしてください。

shirousa01
質問者

補足

いろいろなクラス等を使えば楽にはなるのですが、 作成しているのがアプリケーションではなく、ある動作をするためのクラスなので、なるべく他のクラスや関数は使用しないで作ろうと思っているのです。 それに、メモリーの確保や開放を随時行わなくてはかなりのメモリを占有してしまうため、やはり、newとdeleteを使用するしかないのですが、 確保するデータ型は文字列(char配列)だけでなくさらに複雑なものもあり、扱うクラスが無いものもあるため、やはり確保と開放を確認しながら自分で作ったほうが安定します。 それゆえに、確保と開放の時間を確認する方法が知りたいのです。

関連するQ&A

  • メモリーの確保について

    皆さんはプログラムをするときに入力に応じて配列の大きさが変わるような場合には下記の方法のどれでプログラムしますか?こうすべきなのがベストだ!みないなお考えを聞かせてください。 (1)char str[100]のように大きなサイズを前もって用意しておく。これだとあとからデバック時に100って何か意味があるのかとか悩んでしまったりすると思います。 (2)malloc()とfree()関数を使って動的にメモリーを確保する (3)ポインタ配列を使う。char *strとか。 (4)その他 ご教授をよろしくお願いいたします。

  • new int[変数]で確保しても良いんですか?

    Javaでの配列の確保の方法です。 int size = 100; int[] array = new int[size]; のような確保の方法はどの環境・コンパイラでも思い通りの動作をしてくれますか? C言語では、このような書き方で確保することはできなかったので、Javaでは可能なのか心配で質問しました。 「動的」という意味がまだ完全にわかっていないのですが、上記のような変数の確保は、動的とはいえないのですか?sizeの値をユーザーから受け取れば、確保する大きさはいつも違うようになると思うのですが・・・。 ちなみに下記のようなプログラムで配列の確保を使おうとしています。 static int[] toIntArray(String[] strs){   int[] array = new int[strs.length]; // ←ここで 確保しています。   for(int i = 0; i < strs.length; i++){    array[i] = Integer.valueOf(strs[i]).intValue();   }   return array; } 上記のプログラムはStringの配列からintの配列に変換することを目的にしています。

    • ベストアンサー
    • Java
  • C++ 構造体のnew

    こんにちは C++のプログラムで 構造体 KOUZOUTAIの領域をx個分確保したいと思っています。 構造体のメンバにはポインタは使われていません。 KOUZOUTAI *kouzoutai1; int count = 5; kouzoutai1 = new KOUZOUTAI[count]; delete[] kouzoutai1; CLASSを使用していませんが、問題ないでしょうか?

  • ostringstreamからCの文字列を得る方法

    ostringstreamからCの文字列を得る方法について質問です。 ostringstreamのstr()メソッドを使えば、string型が得られると思うのですが、 以下の様にすると期待する様な結果が得られません。 ostringstream hoge; hoge << "HOGE" << "FUGA"; const char* p; p = hoge.str().c_str(); // NG str()メソッドで取得した結果を一旦string型に入れると期待する文字列を得る事が出来ます。 string tmp = hoge.str(); p = tmp.c_str(); // OK なぜp = hoge.str().c_str();では期待する結果("HOGEFUGA")を得る事が出来ないのでしょうか? コンパイラはVC++ 2010 Express Editionです。 よろしくお願いします。

  • メモリ領域確保に関して

    C言語を始めて3ヶ月の初心者です。 下記のような定義で、領域確保をしたいのですが、 うまい方法がわかりません。 ご存知の方いらっしゃいましたら、 御知恵をお貸し下さいませんでしょうか? <test.h> ================================== #define SIZE_A (5) /* 親構造体 */ typedef struct { int testInt; testSmallStructT *testSmall; // 7バイト構造体の配列 char *testChar; // SIZE_A分の領域*配列数 } testBigStructT; /* 7バイト構造体 */ typedef struct { char str1[3]; char str2[4]; } testSmallStructT; /* メンバ変数 */ testBigStructT gTest[10]; ================================== ここで、あらかじめ全体の領域サイズを算出して、 mallocにてエリア確保を行う方法を求めてます。 また、多数にmallocを使用するとメモリ確保失敗時に、 それまで確保したエリアの開放を行わなくてはいけなくなる懸念から、 できるだけ使用しないようにしたいのです。 メンバ変数gTestを10の配列で持ち、構造体testBigStructTの、 要素testSmallとtestCharを可変の配列として扱いたくポインタ定義をしており、 更に、testCharにSIZE_A(5byte)の領域を確保しようとしております。 最終的には、下記のような使い方をしたいのですが、 メモリ確保の方法がわかりません。 =================================== (EX:) strcpy(gTest[0].testSmall[0].str1,"aaa"); strcpy(gTest[3].testSmall[2].str2,"bbb"); strcpy(gTest[6].testChar[3],"cccc"); =================================== 開放は下記の記述で問題ないと思っております。 free(gTest); 大変申し訳御座いませんが、 ご指摘・ご指導願いませんでしょうか? どうか宜しくお願い致します。

  • mallocで確保したメモリをfree解放する必要

    当方、C言語を勉強中です。 mallocで確保しておいたメモリをfreeで必ず解放するようにと教わりました。 freeで開放しないことをひどく野蛮な言葉で例えられたのですが、それほどまでに必要である実感が実はあまりありません。 ファイルポインタでファイルを開いているときに、プログラムが終了すると開いているファイルを自動的に閉じるように、プログラムが終了すると自動的に解放されるものと思っていたのですが、やはりこちらはプログラム終了後も確保されたままになってしまうのでしょうか。 また、解放しないことによるデメリットで、メモリを圧迫する以外にはなにがあるのでしょうか。 ご教授おねがいします。

  • 可変長構造体をファイルから読み込み処理

    可変長の構造体、 typedef struct 構造体(仮) { char c1,c2; float f1,f2; double d; int size; //↓strのサイズ char str[1]; //文字配列 }構造体(仮); の形式で書かれたバイナリデータファイルがあります。 そのファイルを読み込んでcsv形式で出力する処理を、 ファイルからの読み込む回数を減らしてやりたいと思っています。 その方法を教えていただけませんか? よろしくおねがいします。

  • 質問です

    構造体のプログラムで、 #include<stdio.h> struct example{ char str[4]; /* 文字列 */ int num; /* 番号 */ }; int main() { struct example data[5]; /* 全て0で初期化されているとする */ struct example *ps; ps = &data[2]; ps->str[3]='A'; /* (1)この処理でどこが書き変わるか? */ ps += 2; (*ps).num = 15; /* (2)この処理でどこが書き変わるか? */ ps -= 4; ps->str[0] = 'z'; /* (3)この処理でどこが書き変わるか? */ } と、いうものがあるのですが、質問が、「上のようなプログラムのような処理を行った場合に、ポインタ変数psの中身はその時点でどのようになるか。 構造体変数data[]のアドレスは0x1000、0x1000、0x1010、0x1018、0x1020であるとする。」 という問題で、それぞれ、printf文を使ってpsの変化を実際に見てみればよいと思ったのですが、問題文の意図がよく分からないことと、仮にprintf文を入れた場合、どこにどのような中身で入れたら良いのか教えて欲しいと思っています。 お願いします。

  • newを使った領域の動的確保

    お世話になります。 C++での記述方法なのですが 構造体Testの領域を確保しておいて値を入れます。 確保しておいた領域では領域が不足するときに 不足分を追加したいのですがどうすればよいでしょう? Cではreallocを使えばよいと思うのですが C++ではmallocではなくnewを使ったほうがよいと聞きました。 newした領域を再定義した場合(deleteせずに領域を追加) 先に領域に入れたデータは保証されるのでしょうか? 以下例文ソース*部分 以下例文のソース Test *a; a = new TEST[10]; int cnt; int i; for(i = 0;i<10;i++){  //ここでTESTの配列aに値を入れる } cnt = 12; if( cnt > 10 ){  //予想サイズを上回ったら足りない分のサイズの領域を確保し  //データを入れる  a = new[cnt];//*ここで領域を再確保したら元のa[0]~a[9]の         //データは確実に保持されるのか?         //または他に領域を確保する方法があるのか? } 上記例文ソースでは先にcntで領域を確保すれば良いようにみえますが やりたいことは 先に確保されている領域を広げて 先に入れてあったデータと、広げた領域に入れたデータを使いたい のです。 分かりにくい文章かもしれませんがよろしくお願いします。

  • .NET C++で、構造体の配列をnewで作成しようとするとerror C2440のエラーとなってしまいます

    Visual studio2003 .NET C++で、構造体の配列を作成し、 改めて構造体の配列をサイズ指定して作成しようとすると、error C2440が出てしまいます。 ポインターで宣言したつもりはないのですが、ポインターから配列に変換できないといった項目のエラーなので、 なぜこのようなエラーが出るのかわからずにおります。 typedef __nogc struct TEST { // 省略 }; TEST struct_test __nogc[]; int int_num = 10; struct_test = new TEST __nogc[int_num]; // error C2440: '=' : 'TEST *' から 'TEST []' に変換できません。 ご指摘等ありましたらご回答いただけますと助かります。 よろしくお願いいたします。