• ベストアンサー

freeで開放される範囲

お世話になります 例えばある構造体を、 typedef struct {  char* yoso1;  int yoso2; } kozotai; とし、これをmallocで確保した後中身のポインタにもmallocし、 kozotai* test = (kozotai*)malloc(sizeof(kozotai)); test->yoso1 = (char*)malloc(128); freeで開放すると、 free(test); 中の要素の指すメモリも開放されるでしょうか? 今はどちらか分からないので、 free(test->yoso1);free(test);としています。。。

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

  • ベストアンサー
  • chirubou
  • ベストアンサー率37% (189/502)
回答No.3

malloc() の立場で考えると分かり易いと思います。 kozotai* test = (kozotai*)malloc(sizeof(kozotai)); としてますが、kouzoutai にキャストしているのはmalloc() の外であり、malloc() は自分が確保したメモリ領域の中に、ポインタがあって、そのポインタが指す領域がさらに malloc() されているなんて事は全く知りようがありません。ですから、全て free() するには、 free(test->yoso1);free(test); とするのが正しいです。あるいは、kouzoutai_malloc() と kouzoutai_free() という関数を作り、その中で、上の処理をするという方がキレイかもしれません。 蛇足ですが、malloc() 時には領域の大きさを指定するのに、free() には大きさの指定がないのでしょう?ご存知かも知れませんが、malloc() が返すポインタのアドレスの前に、長さ等の情報が格納されているからで、free() はこの情報を使うので、常に malloc() した分だけを free() できるのです。 ここで敢えて free() の説明を取り上げたのは、C で標準的に使われる関数の大半は、C で簡単に書く事ができます。逆に言えば、それ以上の事をしないのは C のいいところであり悪いところなのかもしれません。 本の記述や仕様を鵜呑みにしないで、内部の処理がどうなっているのか考えてみると、理解もずいぶん深くなりますし、応用も効きます。

masaota56
質問者

お礼

ありがとうございます。 大変参考になりました。

その他の回答 (3)

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.4

No.3さんについて少し細かいですがつっこみです。 >malloc() が返すポインタのアドレスの前に、 >長さ等の情報が格納されているからで C言語で規定されているのはあくまでも、 malloc関数などを実装する処理系において、指定されたサイズの オブジェクトを割り当てその先頭を返すこと。 生存期間が明示的に解放されるまで保持されること。 そして、割り当てられたオブジェクトの先頭から指定サイズの領域が 以降の割り当てで重複しないように割り当てること。 返却したオブジェクトの先頭をfree関数に渡した場合、 この指定された領域を解放し再度、割り当て可能な領域に することなどです。 これらさえ守られていれば、どのようにその情報が管理されるかは、 環境に依存しているため、返却されたアドレスの前後に、 それらの情報が入っているかは、保障されていません。

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.2

>中の要素の指すメモリも開放されるでしょうか? char* 型の変数 yoso1 に malloc した領域へのアドレスが格納されていることを 知っているのはプログラマだけなので、自力で free(test->yoso1); して下さい。

  • rinkun
  • ベストアンサー率44% (706/1571)
回答No.1

freeで解放されるのは渡したポインタが直接参照するメモリのみ。その先の構造は考慮されない。端的に言ってmallocした単位でしか解放できないので、複合構造の場合は段階的に解放していく必要がある。

関連するQ&A

  • free()について

    free()についてです。 よろしくお願いします。 ある構造体Aがあったとして その構造体Aの中に構造体Bのポインタが あったとします。 typedef struct{ char b; short c; } B_t; typedef struct { int a; B_t *bbb; } A_t; この構造体をプログラム中でポインタで扱い mallocで領域確保している場合に(A,B共に) Aをfree()した場合は、Bも開放されるのでしょうか? 以下、質問のサンプルです。 A_t *aaa; aaa = (A_t *)malloc(sizeof(A_t)); aaa->bbb = (B_t *)malloc(sizeof(B_t)); : : free(aaa); /* ←これで、aaaのメンバであるbbbは */ /* 開放されるのでしょうか? */ よろしくお願い致します。

  • メモリの開放について

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

  • メモリ動的確保について

    こんにちはです。 メモリの動的確保なのですが、 typedef struct DATA{ char name[256]; char pass[256]; int money; }BANK; void insert(BANK *p,int max); int main(){ int i; size_t st; BANK *person; person = (struct DATA *)malloc(sizeof(struct DATA)); //person = (struct DATA *)malloc(5); if(person == NULL){ printf("確保失敗\n"); exit(-1); } //memset(person,'\0',sizeof(struct DATA)); と、言う風に、記載ソースは途中ですがメモリをとりました。 mallocの後ろの部分ですが、sizeof(struct DATA)と5ではどうちがうのでしょう??2通りともコンパイルエラーはないです。 5は動的に最大5までとるって事はわかるのですが、struct DATAの方はいくつとるのです??いくつもで入力次第です? そして、動的したのにたいしてmemsetしたら実行エラー(コンパイルは通りました)おきました。動的にたいしてmemはダメなのでしょうか? アドバイスいただけたらありがたいです。宜しくお願いいたします。

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

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

    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); 大変申し訳御座いませんが、 ご指摘・ご指導願いませんでしょうか? どうか宜しくお願い致します。

  • ポインタ配列の動的確保

    ポインタの配列の動的確保について教えてください。 入力した数値をポインタ配列に入れるプログラムです。 下記のように書いてみました。(見づらくてごめんなさい) #include<stdio.h> #include<stdlib.h> #define kensu 3 main() { char abc[kensu+1]={'A','B','C','\0'}; char *ptr[kensu]; int i; printf("3つの整数を入力して下さい。\n"); for(i=0;i<kensu;i++){ ptr[i]=(char*)malloc(sizeof(char)*10); if(ptr[i]==NULL){ printf("メモリの取得に失敗しました"); exit(1); } printf("整数%c:",abc[i]); fgets(ptr[i],10,stdin); if(ptr[i][strlen(ptr[i])-1]=='\n') ptr[i][strlen(ptr[i])-1]='\0'; } for(i=0;i<kensu;i++) free(ptr[i]); } ちゃんと動いているようです。 しかし、ポインタ配列の動的確保をネットで調べてみると、ポインタのポインタ(?)を使って、下記のように2度mallocしています。 #include <stdio.h> #include <stdlib.h> #define N 3 int main(void) { char** arr; int i,j; arr = (char**)malloc(N * sizeof(char*)); /* ポインタ配列を確保 */ /* 配列の要素それぞれにつき、メモリ領域を確保 */ for(i=0;i<N;i++) arr[i] = (char*)malloc(N * sizeof(char));   ・・・ ポインタの配列を宣言して、配列の各要素に動的確保するのと ポインタのポインタを宣言し、ポインタ配列を動的確保して、再度配列の要素に動的確保するのとでは、何か違いがあるのでしょうか? ポインタのポインタを宣言し、ポインタ配列を確保する必要性が良く分かっていないのです。 ネット等で調べて見たのですが、理解力がないのかよく分かりませんでした。 どうか教えてください。

  • mallocとfree

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

  • 構造体内のポインタのポインタにアクセスするには?

    たとえば、 struct a { char **name } という構造体があったとして、 struct *a; a->name = malloc(sizeof(char *) * 3); としたときに、 for(i = 0; i < 3; i++){ a->name[i] = malloc(sizeof(char) * 10); } とするとエラーになります。 a->name配列の各要素をmallocするにはどうすればよいのでしょうか?

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

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

  • 構造体へのポインタの動的確保について

    構造体へのポインタを動的確保しようとmalloc関数を使用すると segmentation faultが起きます。 typedef struct cell{ char *word; int count; struct cell *next; }node_t; という構造体で node_t *ptr=(node_t*)malloc(sizeof(node_t)*num); という風に動的確保しようとするとsegmentation faultが起きました。 gdbを使って調べると Starting program: /home/programII/week05/a.out file1 file2 Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7b4ce36 in ?? () from /lib/x86_64-linux-gnu/libc.so.6 というメッセージが返ってきます。 これはライブラリとのリンクが正しく行われていないということでしょうか? しかし、ポインタの動的確保以外でmalloc関数を使用すると 正常に動作するのでライブラリ自体が無いわけではないようです。 ptr[2]といった風にポインタを参照したいのですが上手くいきません。 よろしくお願いします。

専門家に質問してみよう