• ベストアンサー

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

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

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

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8561/19458)
回答No.2

mallocやfreeで管理されているメモリ(このメモリ領域は「ヒープメモリ」と言います)は「管理データ」と「ユーザーデータ」が交互に並んでいます。 そして「管理データ」には「ここは○○バイト使ってる」とか「ここは○○バイト空いてる」と言うデータが書き込まれます。 そして、mallocは「管理データを先頭から辿り、空きマークが付いている管理データを探し、管理データに使用中マークを付けてから、見つけた管理データの直後にある、ユーザーデータの先頭アドレス」を返します。 また、freeは「ユーザーデータの先頭アドレスを受け取って、その直前にある管理データを書き換え、空きマークを付ける」と言う事をします。

noname#113783
質問者

お礼

詳しい解説ありがとうございます! ヒープ領域はそうやって管理していたんですね。

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

その他の回答 (2)

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

確実に挙動を把握するためにはfree()のソースを確認した方がよいかと。 MS-DOSやらWindowsやらではたいていすでに回答のついている方法で管理しているようです。 # malloc()で確保したメモリ領域が指定されたサイズより大きい。ということはありますが。 そんなワケで、バッファオーバーフローやバッファアンダーフローして書き換えた場合に、その後のmalloc()/calloc()/realloc()/free()等で吹っ飛ぶ。 という不具合発生箇所とその結果がかけ離れた場所に…というコトも起こります。

noname#113783
質問者

お礼

それが手元にライブラリ関数のソースがないんですよ。 サイズが大きいこともあるんですね。 回答ありがとうございました!

全文を見る
すると、全ての回答が全文表示されます。
  • php504
  • ベストアンサー率42% (926/2160)
回答No.1

malloc(calloc,realloc)で確保した領域とポインタをメモリ管理システムが保存しているからです。 freeで渡されたポインタが管理保存しているポインタと一致した場合その確保領域を開放します。

noname#113783
質問者

お礼

なるほどやっぱり管理していたんですね。 回答ありがとうございました!

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

関連するQ&A

  • malloc関数 free開放とはなんですか?

    malloc関数を用いてメモリを確保した後、 必ずfreeで開放を行わなければならないですよね? この開放とはどういう意味なのでしょうか?

  • メモリ操作関数『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言語のmalloc関数、またrealloc関数

    c言語のmalloc関数は確保するメモリの領域を、配列としてのみしか処理出来ないのですか。 つまり、malloc関数で確保したメモリの領域を変数、また多次元配列、また構造体としては処理出来ないのでしょうか。 c言語のrealloc関数は以前の確保したメモリの領域から、確保し直したメモリの領域の場所が変わるかもしれないという事ですが、この場合の場所が変わるという意味は、メモリの領域のアドレスが変わるという事でしょうか。 また、以前の確保したメモリの領域に代入していたデータが使用出来なくなるという事でしょうか。

  • C free関数の開放について。

    独学でCを勉強し始めてる初心者です。 以下の構文で、最後に、 free(p); とあり、確保したメモリ「p」を開放していますが、 確保したメモリ「q」は開放しなくて良いのでしょうか? この場合は同じ部分のメモリを確保しているからqは開放しなくて良いということなんでしょうか…宜しくお願い致します。 #include <stdio.h> #include <stdlib.h> int main(void) { int *p; p=malloc(sizeof(int)*3); if(p==NULL) exit(1); p[0]=10; p[1]=20; p[2]=30; printf("%d\n",p[0]+p[1]+p[2]); free(p); return=0; }

  • free()について

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

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

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

  • 関数へのポインタ渡し

    下位関数へポインタのアドレスを渡して(器を渡して) 内容を設定してもらうというのは、よくやることと おもいます。 そのポインタの領域は、普通は上位関数で実体を確保する と思っていたのですが、下位関数での実体確保することは 可能なのでしょうか? 対象はc言語です。 宜しく御願い致します。

  • malloc関数の使い終わった後の開放について

    今、Cでmalloc関数を使った簡単なプログラムを作っています。 それを作っているときに思ったのですが、mallocを使って出来た領域を、freeで開放する前に異常終了したとします。 そういったときに開放する方法はないのでしょうか? 学校の先生から聞いた話によると、「パソコンを次に立ち上げたときに開放される」みたいなことを聞いたのでやらなくてもいいのかも知れませんが、気になるので教えてください。

  • フリーメールをはじくのは・?

    登録サイトでよくフリーメールでは登録できない・・・というのがあって 実際フリーメールだと「このアドレスでは登録できません」とか返ってきます。 あれって、どういう仕組みなんですが? まさか世界中のフリーメールを登録しておいて、それに合致した場合はじくってことではないとおもうのですが? プログラムのスキルがあるわけではないので、おおざっぱなロジックだけでも教えていただけたらと思います。

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

    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; }

このQ&Aのポイント
  • 印刷ジョブには普通に出るのに白紙が給紙される。
  • 突然PCからの印刷が白紙で出ます。PCからのテストプリントは出来ます。Wi-Fiでの印刷もできます。
  • キヤノン製品についての質問です。
回答を見る