• ベストアンサー

メモリ管理

Cでメモリー管理に関して次のようなLIBがあればいいなと思っています。 目的:使うたびに確保、開放では効率がわるいので共通の領域を使いまわす 条件:XXXMallocで使用するサイズはバラバラ (1)メモリーをまとめて「XXXLIBの領域」用に確保 (2)XXXMallocを実行するとメモリ管理が「XXXLIBの領域」から切り出してくる ここで足りなければ自動で大目に確保 (3)不要になったらXXXReleseで開放し、あとで使いまわしする こんなものが存在する事を知っている方は教えてください。

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

  • ベストアンサー
  • MrBan
  • ベストアンサー率53% (331/615)
回答No.4

malloc/freeのヒープ実装も、 近いことやってたりすることが多々あるわけですがご存知ですか? (本当に素直に毎回OSからメモリ取ったりせず、内部で使いまわしたり) どこのライブラリをお使いですか? で、既出のような例えばサイズが同じとかタイミングが保証できるとか 「汎用でない、美味しい条件」がないかぎり、mallocでもそう差はないと思います。 で、この手の条件がある場合のパターンがメモリプールで、 これだと格段に早く/効率よくなりえますが、一般には汎用性が犠牲になります(使い方に条件が付く)。これも既出。

ritomo
質問者

お礼

回答が遅くなり生ました。 malloc/freeが近いことやっている件は知りませんでした。 lib名は環境が手元にないので不明ですがOSはlinuxです。 mallocでもそう差はないというのはサンプルで試して見ることにします。 たいへん参考になりました。

その他の回答 (5)

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.6

★標準ライブラリなどでは malloc / free 関数ぐらいでしょう。 ・回答者 No.5 さんと同じように私も以前にメモリプールを扱う自作ライブラリを作成して  使っていました。もちろん、今でも大量のデータを確保や解放を繰り返すタイプのソフト  では、自前のライブラリからメモリを確保/解放をしています。 ・質問者さんも暇があれば1度、メモリ管理のライブラリを自作してみるのはどうでしょう。 ヒント: ・私の作ったメモリ管理ライブラリは、昔の MS-DOS 時代のメモリ管理ブロック(MCB)を  ヒントにメモリのデータを鎖のように繋ぎ管理させました。しかし、このままでは単方向で  しか空き領域を検索できないので確保領域を探すのに時間が掛かります。そこで空き領域用に  空きデータを鎖のように繋ぎ単方向リスト管理させます。これで、開き領域の検索が少し高速  になります。それとメモリを解放するときには、開き領域のチェインに登録させますが、同時  に開き領域の合併処理も行います。→この合併処理の工夫がポイントです。私は使用・未使用  の独自メモリマップをテーブルとして用意して、そこから合併するかの判定を行いました。 ・また、メモリ領域が不足したら realloc などで容量を拡張します。  ただし、拡張するとポインタ位置がずれたりしますので、データはポインタ管理ではなくて  先頭メモリブロックからのオフセット値で管理して、データの読み書き時にポインタに変換して  操作を行います。 最後に: ・上記のはメモリ管理の一例です。 ・もっとよいメモリ管理のライブラリをそのうち作成する予定ですが、今現在は保留状態です。 ・以上。参考にして下さい。

ritomo
質問者

お礼

ご回答ありがとうございます。 メモリ管理は自前で作成することになりそうです。 空きデータを鎖のように繋ぐ方法、オフセット値の管理は大変参考になります。

  • noocyte
  • ベストアンサー率58% (171/291)
回答No.5

私は昔,2種類のメモリプール (固定長データ用と可変長データ用) ライブラリを作り,今でも時々使ってます. (いずれ暇なときに自分のサイトで公開しようかとも考えていますが.) 可変長データ用は #2 さんが書かれているように,最初に大きな領域を 確保しておき,先頭から順に要求されたサイズを割り当てていく方式です. これだと malloc/free を1回ずつ呼べばよく,高速化できます. ただし割り当てた領域を個別に解放することはできません. また,さまざまなサイズのデータが混在するので,できるだけ隙間が できないようにするために,割り当てる際にはサイズだけでなく アラインメントも指定する仕様にしています. # malloc() の実装に興味を持っている人でも,意外とアラインメントの # ことを知らない人が多いことを以前知って驚きました.

ritomo
質問者

お礼

返事が遅くなりました。アラインメントは今回勉強させていただきました。ありがとうございます。

  • koko_u
  • ベストアンサー率12% (14/116)
回答No.3

>条件:XXXMallocで使用するサイズはバラバラ アロケーションされるサイズがバラバラでは malloc & free に敵う実装は凡人には無理。

ritomo
質問者

お礼

返事が遅くなってすみません。参考になりました。

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

メモリプールがそれに該当するかと思います。既成の機能が使えるかどうかは環境に依存します。例えば、μITRONでは、cre_mplでメモリプールを生成し、get_mplでメモリブロックを獲得、rel_mplで解放します。メモリプール全体が不要になれば、丸ごとdel_mplで破棄できます。 アプリケーションでの用途によっては、もっと簡単な実装も可能です。例えば、特定のモード内でだけ使うアロケータであれば、次の割り当て位置を指すポインタだけを単純に進めていき、モードから抜ける際にまとめて解放する等です。 排他制御も不要になるケースが多いので、mallocに比べて桁違いに高速になる可能性があります。

ritomo
質問者

お礼

返事が遅くなってすみません。μITRONのページを見て見ました。イメージに近いものです。 アプリケーションでの用途はサイズがバラバラで使いまわすので、つくりは簡単にはいかなそうです。

noname#96023
noname#96023
回答No.1

要はアドレス管理だけをできればよいので、自分で作れそうですね。 ただ、どれくらいの効率が良くなるかわからないですし、バグると致命的になりそうなので自分は遊び以外で使う気はしませんが。

ritomo
質問者

お礼

返事が遅くなってすみません。たしかにリスクはありますよね。

関連するQ&A

  • [C言語]freeする領域のサイズは誰が管理?

    趣味でプログラミングの勉強をしています。 C言語で、ふと疑問に思いましたので質問させていただきます。 動的に領域を確保するときにはmalloc()にサイズを与えて、その領域のアドレスを取得します。 で、解放するときにはfree()に領域のアドレスを与えます。 ここで疑問に思ったのですが、領域を開放する場合にはその領域のアドレスとサイズが必要ではないかと思うのですが、free()ではアドレスしか与えませんよね? 誰かがアドレスとサイズが対になった情報を管理する必要があると思うのですが、誰が管理しているのでしょうか? 単純に考えてコンパイルしてできた実行形式のファイル中(あるいは呼ばれる外部ライブラリ?)にその機能があると思うのですが、それで合っていますか? よろしくお願いします。

  • 自アプリ内のメモリを管理したい

    こんにちは。 現在C/C++でプログラムを組んでいます。 C/C++でメモリを確保、開放するにはmalloc、new、free,deleteを使うわけですがアプリケーションが開始された時点で、ある一定のメモリを確保しておいてそのメモリから分け与えたりデフラグしたりして自分のアプリで使うメモリを管理したいと思っています。 BYTE* g_allMemory;//グローバル変数 g_allMemory = new BYTE[1024]; プログラムを実行した時点でこのようにメモリを確保しておき要所要所で自作関数を利用してメモリを分け与えたりデフラグしたりして使えるようにしたいのです。 しかしデフラグした瞬間に変数のアドレスがずれてしまって使い物になりません。 これを解決したいのですがアドバイスやお勧めのホームページや参考文献などがあったら紹介をお願いします。

  • GDI+におけるメモリの開放について

    C++でGDI+のコードを書いています。 たとえば Gdiplus::Bitmap bmp(1000, 1000); を一度呼ぶと、アプリケーションを終わらすまで確保した領域が開放されず、 繰り返し呼ぶと使用メモリがどんどん増えていってしまいます。 確保したBitmapを開放するにはどうしたらよいのでしょうか?

  • Linuxのメモリ管理

    Linuxのfreeメモリとは、Top等のコマンドで見えるfree+buff+cacheと思っていますが、Linuxを使用しているとfree領域がどんどんなくなっていき、buff, cache領域が増加していきます。 free領域が枯渇しそうになって(表示上10Mぐらい?)いて、swapdとかが動作しているにもかかわらず、buff, cacheを開放したりしないのでしょうか? この辺のLinuxのメモリ管理方法をご存知の方、いらっしゃいましたら御教授願えませんでしょうか 掲載HP等でも良いので情報頂ければ助かります。 宜しくお願い致します。

  • メモリリークについて

    VC6.0でデバッグ実行すると Detected memory leaks! Dumping objects -> ソースファイル名(932) : {136739} normal block at 0x00FD4AC0, 0 bytes long. Data: <> メッセージがあり メモリがリークしているようです メッセージやソースから察するに 0バイトの領域を確保し それを解放したときに起こっているようです 領域をmallocして 解放ではNULLでなければ解放 という処理はしてはいけないことなのでしょうか 0バイトの領域を確保した場合 又は0バイトの領域を確保しないように 処理しないといけないのでしょうか? 知識のある方よろしくお願い致します

  • 配列を宣言した際メモリ内の様子

    「配列」を宣言した際、メモリ内では何が起きているのでしょうか? 配列宣言した際にメモリ内にて、複数のデータを格納する為に、メモリー領域がまとめて確保され、その確保した領域に名前が付けられるのでしょうか? 分かりやすく教えてください。 よろしくお願いします。

  • メモリの開放について

    いつもお世話になっております。 メモリ開放のお作法について教えてください。 int* p ; p = (int*)malloc( 100 * sizeof( int ) ) ;  ※ p = (int*)malloc( 100 * sizeof( int ) ) ;  ※ p = (int*)malloc( 100 * sizeof( int ) ) ; free(p); このような記述をした場合、※の付いている2行でメモリ確保した 領域は開放されるのでしょうか。 (メモリ確保に失敗した場合の処理は省略してます。) よろしくお願いします。

  • メモリ操作関数『malloc(),free()』

    /*10バイトのメモリ領域を確保し、その領域に文字列"Allocate"を代入せよ。*/ /*ただし、確保した領域は、プログラム終了までに開放すること。*/ #include<stdio.h> #include<stdlib.h> void main(void) { char *ptr; ptr = (char *)malloc(10); printf("Allocate\n"); free(ptr); } 今、ライブラリ関数を勉強しています。 この問題をとりあえず作ってみて、実行も成功したのですが、10バイトのメモリ確保の数値を変えても、何も変わらないため本当に問題の要求どおりのプログラムが作れているのか謎です。 間違っているなどのアドバイス宜しくお願いします。

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

    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で確保するメモリの領域を限定する方法

    mallocで確保するメモリの領域を限定する方法というものは存在するのでしょうか? 例えば、 mallocを使ってメモリを確保するときに、 アドレス:0x00001000から0x00002000の間でメモリを確保してください。 といった感じです。 宜しくお願いいたします。

専門家に質問してみよう