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

このQ&Aのポイント
  • C言語で動的に領域を確保する際、malloc()関数を使って領域のアドレスを取得します。しかし、領域を解放する際にはfree()関数にアドレスしか与えず、サイズが必要ないことが疑問です。このサイズは誰が管理しているのでしょうか?
  • C言語において、動的に確保した領域を解放する際にはfree()関数を使います。しかし、この際には領域のアドレスのみを与えており、サイズを指定する必要がありません。では、領域のサイズは誰が管理しているのでしょうか?
  • C言語で領域を動的に確保する際にはmalloc()関数を使用しますが、解放する際にはfree()関数にアドレスを渡すだけでサイズを指定する必要はありません。このため、領域のサイズはどこで管理されているのか疑問に思います。
回答を見る
  • ベストアンサー

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

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

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

  • ベストアンサー
  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.3

ランタイムライブラリ次第。ってところもありますけどねぇ……。 現在の一般的なOSならメモリ割り当てなんかはOSが管理しています。 ソレをC言語のランタイムライブラリで覆い隠している場合もあるでしょう。 その際にサイズなどをどう管理するかはランタイムライブラリ側の問題になります。 # まぁ、そう考えればOS側でもサイズなどの情報を持っていることになりますが…。 アプリケーション起動時にそこそこのサイズでOSからメモリを取得、malloc()などがアプリから呼ばれた時にそこから切り取って使う。という方法をとってもいいワケです。 VisualStudioの製品版ならランタイムライブラリのソースコードも入手可能ですし、GNU Cライブラリならそちらもソースコード一式取得可能でしょう。 X68kのOSではリンクリスト構造で管理してましたねぇ。 # 参考にしたMS-DOSでもたぶん同様…でしょう。 strcut {  前のメモリ管理ブロックへのポインタ  サイズ  次のメモリ管理ブロックへのポインタ } みたいな構造体をmalloc()で確保した領域の先頭に置いて、 malloc()の戻り値として返却するときに管理用のメモリブロックの直後のアドレスを返す。 とか……。 で、バッファオーバーランやバッファアンダーランするとこの管理ブロックを破壊するのでfree()や次のmalloc()を実行した際に管理ブロックのリスト構造が壊れてて吹っ飛ぶ…とかね。 # Windowsなら一般保護違反とかですね。X68000ではバスエラーだったかなぁ…。 malloc()で返されたアドレスを保持していない(ポインタ操作で進めたとか)の場合も、free()で渡されたアドレスから管理ブロック探そうとしても変なアドレス指しているので…と。 てきと~に見つけた例。 http://www.valinux.co.jp/technologylibrary/document/linux/malloc0001/

siffon9
質問者

お礼

ご回答ありがとうございました。 答えとしては、アプリケーションからみるとランタイムライブラリが行う。 ただし管理のやりかたは色々あるよ、ということですね。 ご提示いただきましたリンク先の資料は参考になりました。

その他の回答 (3)

  • wormhole
  • ベストアンサー率28% (1619/5652)
回答No.4

>「管理する側」とは具体的に何を指すのでしょうか? Cのランタイムライブラリです。 linuxなどでは、Cのランタイムライブラリはソースが公開されていたりしますので読んでみるといいです。 https://www.gnu.org/software/libc/ http://www.uclibc.org/ http://dmalloc.com/ また管理方法にもいろいろあります。 http://ja.wikipedia.org/wiki/Malloc

siffon9
質問者

お礼

ご回答ありがとうございました。 ソースを直接読むのは、今の私にはちょっとキツいですw 管理方法はいろいろな方式があるのですね、勉強になりました。

  • kngj1740
  • ベストアンサー率18% (197/1052)
回答No.2

C言語の教科書(カーニンハン?)などに例が載ってます。与えたメモリのスタートアドレス、サイズは管理する側で覚えてます。

siffon9
質問者

お礼

ご回答ありがとうございました。 申し訳ありませんが、今ひとつわかりません。 「管理する側」とは具体的に何を指すのでしょうか?

  • uruz
  • ベストアンサー率49% (417/840)
回答No.1

コンピュータに搭載されているメモリーは全てOSが管理しています。 malloc()でOSに使用したいサイズを申請します、するとこのアドレスを使いなさいと許可が下ります、解放はfree()でOSにこのアドレスで許可された領域はもういらないよと申請します。

siffon9
質問者

お礼

ご回答ありがとうございました。 以前、何かで読んだのですがOSからはある程度まとまった量の領域を一度に確保して、mallocはその領域から切り売りしていると書いてありました。 とすると、mallocから与えられる領域の管理はOSではないのかと思い質問させていただきました。

関連するQ&A

  • mallocによる確保外の領域への参照

    構造体をmallocにより動的確保を行っていたのですが、例えば typedef struct _point{ int x, y; } point; point *pelem_point; pelem_point = (point *)malloc(sizeof(point)*5); このように、point型の構造体を5つ確保するとします。 しかし、 (pelem_point+100)->x = 1; (pelem_point+100)->y = 2; printf("%d\n", (pelem_point+100)->x); printf("%d\n", (pelem_point+100)->y); とやったら、確保していない100個先のところも構造体として利用できました。 なぜなのでしょうか。 自分の考えではこのようになりました。 mallocによりヒープ領域から適当な空いているメモリのアドレスが渡されるため、そこからはヒープ領域より先に、限りがあるまで進めてしまうために確保外のサイズにアクセスしても使えてしまっている。 また、mallocにより確保した場合は使用中のラベルがはられるため他に侵されることはないが、先の例のようにmallocによって確保してない場合はいくら使用できたとしても、空いているとコンピュータでは認識されるため、何かヒープ領域を使う場合に勝手に上書きされてしまう可能性がある。 しかし、この考えでも、なぜ確保外の領域が構造体のサイズ分ずつ区切られているのか納得いきません。 わかる方いましたらよろしくお願いします。

  • C/C++言語のメモリについて

    C言語でメモリを2種類?に分けると、スタックとヒープがあります。 ヒープは mallocなどで確保し、freeで解放しますがスタックは解放する必要がありません。 そのスタックは通常、何バイトまで可能なのでしょうか? あと関数外のファイルの先頭に int[1000000];とした場合、このメモリはmallocで確保していませんが、 どこに作られるのでしょうか? 私のパソコンはメモリが2GBでWindows2000ですが、CやC++で最大、何バイトまでメモリが使えますか? また、一番多くメモリを確保できるなら、OSはなんでも構いません。 解釈等も間違っていたらご指摘していただきたいです。

  • 動的なメモリ領域の確保

    double型変数5個分のメモリをmalloc関数により確保し,その確保した要素のアドレスを表示するように,プログラムを作る問題で、 (注)に「 %pで表示するためには,double型へのポインタ(double *)をvoid型へのポインタ(void *)にキャストする必要がある.」と書かれていたのですが、どういうことでしょうか? 以下のようでいいのでしょうか? #include<stdio.h> #include<stdlib.h> #define COUNT 5           // 動的に確保するメモリ領域数を示すマクロ定数の定義 int main(void) {  // 動的に確保するメモリ領域のアドレスを保持するポインタ変数の宣言  double * pointer;  int i;                  // for文で使用する変数の宣言  // int型変数5個分のメモリ領域を確保  pointer = (double *)malloc(sizeof(double) * COUNT);  if(pointer == NULL) {        // メモリ領域の確保が失敗した場合   printf("メモリ領域を確保できませんでした.\n");   exit(1);                // プログラムの終了  }  for(i = 0; i < COUNT; i++)   printf("%d番目のアドレスは%pです.\n", i + 1, pointer + i);  free(pointer);            // 確保したメモリ領域の解放  return 0; }

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

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

  • C++のnewの使い道

    最近C++を勉強しているのですが、new演算子はどういうときに使うべきでしょうか? メモリを動的確保できるのはわかります。 Cのmallocのようなものと考えていいのでしょうか? つまり、関数内でメモリを確保してそのアドレスを返すとか、コンパイル時に不明なサイズのメモリを実行時に確保するとか、任意のタイミングでメモリを開放したい場合などに使うものでしょうか。 ある参考書を読んでいると「引数つきコンストラクタを呼び出す場合はnewでインスタンス生成する」と書いてありました。 デフォルトコントラスタならnewなし、引数付きならnewあり、ということらしいです。 なぜこんなことをする必要があるのでしょうか?

  • 動的メモリとexit(C言語)

    fpA=fopen("name1", "r"); fpB=fopen("name2", "r"); fpC=fopen("name3", "r"); if(fpA==NULL || fpB==NULL || fpC==NULL){ exit(1); } fpAとfpBのファイルオープンに成功してfpCで失敗した場合、exit(1)によってfpAとfpBはクローズされますよね? じゃあ、 a=malloc(size); b=malloc(size); c=malloc(size); if(a==NULL || b==NULL || c==NULL){ exit(1); } aとbのメモリ確保に成功してcで失敗した場合、aとbのメモリはどうなっちゃうんでしょう?exitは動的メモリも解放してくれるのですか? とりあえず以下のようにしてますが…。 a=malloc(size); b=malloc(size); c=malloc(size); if(a==NULL || b==NULL || c==NULL){ free(a); free(b); free(c); exit(1); }

  • free関数の挙動がわからない

    free関数は動的確保したメモリを空き領域として登録するそうですが、アドレスを渡すだけでなぜ確保したメモリ領域を開放できるのでしょうか?アドレスだけでメモリ全体の大きさがわかる仕組みがあるのでしょうか。 回答よろしくお願いします。

  • mallocとfree

    struct list *p; /* 記憶領域の確保 */ if ((p = (struct list *) malloc(sizeof(struct list))) == NULL) { printf("malloc error\n"); exit(1); } とサンプルプログラムがあるのですが、if分の意味がわかりません。 また、mallocを使った場合freeで開放とあるのですが、 どういう意味なのかわかりません。 よろしければ、上記2つの点について教えてください。

  • free()について

    free()について int *x; x = malloc(4*3); *x = 1; *(x+1) = 10; *(x+2) = 100; free(x); としたとき free(x)ではどうして確保した分のメモリを開放できるのですか? 引数xから最初の4バイト分はわかりますが、ぴったり確保した分を開放できるのが理解できません

  • メモリ管理

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

専門家に質問してみよう