• ベストアンサー

入れ子になった構造体について

以下のように定義した、2重に入れ子になった構造体があります。 これを、mallocを使ってエリアを確保した後、初期化しています。 例では、各構造体の項目数が少ないのですが、 項目が増えた場合、下記のような初期化方法だと面倒だと思います。 もっとよい方法があるのだろうと思っているのですが・・・。 下記は私の試行錯誤結果なので、「普通はこうやるんじゃないの?」という方法などがあればご教授願います。 /* -- 構造体定義 -- */ typedef struct {   char data[16] ; }D_TAG ; typedef struct {   char name[16];   D_TAG *d ; }F_TAG ; typedef struct {   char name[16] ;   F_TAG *f ; }T_TAG ; /* -- 変数定義 -- */ T_TAG *t ; /* -- エリア確保 -- */ t=(T_TAG*)malloc(sizeof(T_TAG)*10); for(i=0;i<10;i++) {   t[i].f=(F_TAG*)malloc(sizeof(F_TAG)*10);   for(j=0;j<10;j++) {     t[i].f[j].d = (D_TAG*)malloc(sizeof(D_TAG)*10);   } } /* -- 初期化 -- */ for(i=0;i<10;i++) {   memset(t[i].name , 0x00, sizeof(t[i].name));   for(j=0;j<10;j++) {     memset( t[i].f[j].d, 0x00, sizeof(D_TAG)*10);     memset( t[i].f[j].name , 0x00, sizeof(t[i].f[j].name));   } } よろしくお願いいたします。

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

  • ベストアンサー
  • TALLY-HO
  • ベストアンサー率29% (103/354)
回答No.1

初期化値が0なら、mallocではなくcallocでメモリ確保 されてはどうでしょう?自動で0に初期化してくれますよ。

参考URL:
http://www.bohyoh.com/CandCPP/C/Library/calloc.html
sunasaka3
質問者

お礼

早速のご回答ありがとうございます。 「calloc」は使ったことが無かったです。 早速使ってみました。ありがとうございます! ちなみに、もし、スペースなど0以外で全て初期化したいような場合は、地道にやることになるのでしょうか?

その他の回答 (4)

  • VirtualT2
  • ベストアンサー率58% (18/31)
回答No.5

なんとなく、sunasaka3さんのやりたい事が 見えてきたような思い込みを当方が勝手にしたので 参考程度に。 T_TAG/F_TAG/D_TAGの各内部が動的で必要数も変わるんですな。 高速化の手助けには成らないですけど、まとめ方の例として 線形リストを用いて観てはいかがでしょうか。 例(あえて片方向線形リストっ) typedef struct _tag_N_TAG { // データ格納構造体  _tag_N_TAG *pnext; // 自分の次に来るN_TAG構造体へのポインタ(NULL時、終末)  _tag_N_TAG *pdata; // 更に下に格納してるデータ(NULL時、下にデータ無し)  char *name; // 格納してる名前 } N_TAG; // N_TAGを確保し初期化、線形リストに追加する処理 // **pTOP: この横階層のトップ(絶対!でないとリストが破綻する(横着してるから… // name : 名称 N_TAG* CreateN_TAG(N_TAG **pTOP, char *name) {  N_TAG *p;  if( !(p = (N_TAG*)malloc(sizeof(N_TAG))) ) return(NULL); // メモリ不足  if( !(p->name = (char*)malloc(strlen(name)+1)) ) { // 名前の領域を確保   free(p); return(NULL); // メモリ不足  }  p->pnext = *pTop; // 作成したpの次を引数である先頭にし  *pTop = p; // 作成したpが先頭になる  p->data = NULL; // 作成したばかりなので下にデータは無し  strcpy(p->name, name); // 名前をコピーする  return(p); // 作成したN_TAGであるpを返す } 使用例 void main(void) {  N_TAG *root = NULL;  N_TAG *p;    p = CreateN_TAG(&root, "a"); // root階層に付け足す  CreateN_TAG(&root, "b"); // 付け足す(リストをたどれば  CreateN_TAG(&root, "c"); // 足す   作成したN_TAGを探せるのでポインタ捨てる)    CreateN_TAG(&p->pdata, "m"); // aの下方階層に付け足す  CreateN_TAG(&p->pdata, "n"); // 付け足す  p = CreateN_TAG(&p->pdata, "o"); // 足す    CreateN_TAG(&p->pdata, "q"); // oの下方・・・ry    // cを探す(nとか下の階層だと、関数作らないとダメなので…横着…(;;  p = root;  while(p) { if(!(strcmp(p->name, "c"))) break; p = p->pnext; } // こないなカンジ  if(p) { /* pは、"c"のN_TAGポインタ */ }    // 後始末… 書かなきゃダメか…  ReleaseN_TAG(root); // 下記 } // pR:階層のトップで無いとダメ。 void ReleaseN_TAG(N_TAG *pR) {  N_TAG *p, *q;  p = pR;  while(p) {   if(p->pdata) ReleaseN_TAG(p->pdata); // 下方階層があるなら、再帰する   q = p; // 開放用   p = p->pnext; // 次を取り出す   free(q->name); // 名称領域開放   free(q); // 自身開放  } } // ----------------------------------------------------------------------------- イメージ的には       ↓pnextね  root == c -> b -> a -> NULL (横階層 pnext->pnext…)           | ←pdataね(下階層 pdata)           o -> n -> m -> NULL           |           q -> NULL てな、カンジの構造が作れます。 CreateN_TAG関数は、常に先頭に足していく様に作ったので 上記のようなデータの並びになります。 データの取り出しは、rootからpnextやpdataをたどっていきます。(開放もね) 途中のデータを削除・追加・ソートとか考えてない作りです。(この例はね) 理解できれば、双方向な線形リスト化や、 削除・追加関数・ソート関数の作成も容易になります。 PS.判りづらいかも… ++余計な、おせっかいかも +++すみません…(TT ++++コードにロジックエラーが在るかも…

sunasaka3
質問者

お礼

線形リストですか。 情報処理とかの勉強で出てきますが、実際にやってみたことは無かったです。 たしかに、やりたいことを図示するとリストになるのですよね。 やってみたいと思います。 ありがとうございました!

  • nitscape
  • ベストアンサー率30% (275/909)
回答No.4

なんとなく構造が複雑でプログラミングが進んでいくとメモリリークを起こしてしまいそうですね。入れ子を使わずに typedef struct {   char data[16];   char name1[16];   char name2[16]; }T_TAG ; のようにしてしまってはダメなのですか?後々の処理でdataやnameのポインタが移動するからというのでしたら typedef struct {   char* data;   char* name1;   char* name2; }T_TAG ; のようにしてポインタ扱いにしてしまってもいいと思いますし... この手の入れ子を使わなくてはいけないというような条件がないのでしたら見やすいコードにするとメモリリークやバグの可能性も減らせていいかと思います。

sunasaka3
質問者

お礼

アドバイスありがとうございます。 自分としてもあまり複雑にはしたくなかったのですが、方法が思い浮かばず・・・。 今回、このような構造にしたのは、それぞれ入れ子になっている構造体のサイズが、nameの配列要素ごとに違っている為です。 なので、実際は、質問のように、まとめてmalloc後、纏めて初期化ということはしていません。 イメージとしては、以下のようにDBっぽい扱いです。  ・T_TAG→テーブル名を格納  ・F_TAG→各テーブルのフィールド名を格納  ・D_TAG→各フィールドのデータを格納 テーブル毎にフィールド数が異なり、各テーブルでデータ数が異なるものを纏めて扱うことが目的です。 テーブル名、フィールド名にあたるものはも外部ファイルから取得して動的に作成しなければならないのです。 なんか、無理やり感が在るのですが・・・。 いい方法があればアドバイスいただければ幸いです。 よろしくお願いいたします。

  • VirtualT2
  • ベストアンサー率58% (18/31)
回答No.3

>ちなみに、質問では省いたのですが、freeはmallocの逆順に入れ子の内側からやっていく、ということになるのでしょうか? >(今は、そうしています。) 補足回答です。 ならべくなら、入れ子の内側からの方が良いです。(確保した順番の逆の意) 開放メモリの分断化を防ぐ観点からはですが… しかしながら、メモリアロケイターが確保の逆順に開放したからといって、 必ずしも、最適にメモリを管理してくれてる保証はないので、何とも言えません。 (確保時にメモリセル自体が分断化された状況ってのありうるし…) 今回、質問した例だと内側から開放していかないといけないですね。 (外側からだと、内側で確保したメモリポインタが参照できなくなってしまうから…(^-^) 念の為(しつこい?)外側から開放した場合… F_TAG型のt[0].f[1]を開放してしまったら、 D_TAG型のt[0].f[1].dに格納されていたメモリ確保ポインタが参照・開放出来なくなってしまう。 ※開放する前に他で取って置けば別ですが… 具体例: char *a = (char*)malloc(10); char *b = (char*)malloc(10); free(a); free(b); ってのは、アリです。(釈迦に説法っぽぃなぁ…) と、省かれた質問のアドバイスでした。 更に補足~ #2で書いたC++部 delete[] t; ってのは、 delete時にT_TAGのデスクトラクター~T_TAG()が呼ばれ、 ~T_TAG()の中から、~F_TAG()が呼ばれ、 ~F_TAG()の中から、~D_TAG()が呼ばれます。 そして、戻っていく訳なので… つまり、最内側から開放されていく訳です。

sunasaka3
質問者

お礼

確認できて安心しました。 ありがとうございました!

  • VirtualT2
  • ベストアンサー率58% (18/31)
回答No.2

#1さんのcalloc使用に同意しますね。 各構造体毎に初期化マクロを用意するというのも、手です。 #define m_clrD_TAG(prm) memset(prm->name,0,sizeof(prm->data)); #define m_clrF_TAG(prm) { memset(prm->name,0,sizeof(prm->name)); prm->d = NULL; } #define m_clrT_TAG(prm) { memset(prm->name,0,sizeof(prm->name)); prm->f = NULL; } m_clrT_TAG(&t[0]) とか。 まあ、一部クリアーとか発生するような状況でもない限りは…(ポインタもクリアーしてるから、リークとかに注意) 以下は、とっても暇な時にでも… C++なら構造体にコンストラクターつけて、 クリアーをする手があります。 へたっぴな、C++で申し訳ないですが あくまで御参考に~。(Cオンリーなら、全然参考にならないデス) 定義 class D_TAG { public: char data[16];  D_TAG() { memset(data, 0, 16); } // newで作成する時に自動的に呼ばれる  ~D_TAG() {} }; class F_TAG { public: char name[16];  D_TAG* d;  F_TAG() { memset(name, 0, 16); d = NULL; }  ~F_TAG() { if(d) delete[] d; } // delete時に呼ばれる。dが確保されているなら開放する }; class T_TAG { public: char name[16];  F_TAG* f;  T_TAG() { memset(name, 0, 16); f = NULL; }  ~T_TAG() { if(f) delete[] f; } }; 初期化使用例 T_TAG* t = new T_TAG[10]; // newで作成時に初期化される for(int i=0;i<10;i++) {  t[i].f = new F_TAG[10];  for(int j=0;j<10;j++) {   t[i].f[j].d = new D_TAG[10];  } } 開放例 delete[] t; // コレだけで全部まとめて開放してくれる(tの中のfもfの中のdもね) delete[] t[1].f[5].d; t[1].f[5].d = NULL; // コレは、必ず! ※[T_TAGのf][F_TAGのd]は、各個に開放したら必ずNULLを入れないといけない。 PS. C++へのステップアップにと勝手に私が思い込んでみました。 ご迷惑でなければ良いのですが… 「C言語しか環境的につかえんのだよ、だから質問してるんだよ!」 って、実は!?だったら、すみません。 組み込みexeGCCでヒープが湯水のようにつかえない、とかだったり…

sunasaka3
質問者

お礼

ご回答ありがとうございます。 今回は、「Cオンリー」なのです・・・。 C++の方は今後の参考とさせていただきます。 callocを使ってやってみたのですが、遅くなってしまいちょっと微妙な状況です。 もともと3秒くらいかかって「遅い」といわれていたのですが、callocだと5秒かかってしまい・・・。 ですので、マクロを使用する方法で試してみます! ちなみに、質問では省いたのですが、freeはmallocの逆順に入れ子の内側からやっていく、ということになるのでしょうか? (今は、そうしています。)

関連するQ&A

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

    たとえば、 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するにはどうすればよいのでしょうか?

  • 構造体の配列のアロケート等の方法

    基本的な事かもしれないのですが、 構造体の配列をダブルポインタで返すような関数を作成したいのですが、アロケートの仕方と、そもそも配列をダブルポインタで扱う方法が良く分かってないのかもしれません。 どなたかご教授頂けないでしょうか? Webで調べてもなかなか合ったものが見つからないため、こちらに質問させて頂きました。 イメージしているものを↓に途中まで作ってみました。これも合っていない部分があるかもですが。。。 要はアロケートして構造体の配列を作成する部分と、それをfor文で回して参照する方法が、分かっていない主なところです。 #include <stdio.h> #include <memory> typedef struct member{   int  id;   char*  name; } *member_t; int get_result(member_t *pobj) {   member_t* obj = NULL;   obj = (member_t*)malloc(sizeof(member_t));   memset(obj, 0x00, sizeof(member_t));   char* nm = NULL;   char cnmtmp[] = "nakayama";   nm = (char*)malloc(strlen(cnmtmp)+1);   memset(nm, 0x00, strlen(cnmtmp)+1);   memcpy(nm, cnmtmp, strlen(cnmtmp));   obj->id = 100;   obj->name = nm;   *pobj = obj;   return 0; } int get_resultList(member_t **ppobj) {   /*    * ココ    */   return 0; } void main() {   member_t* obj = NULL;   get_resultList(&obj);   for(int i = 0;;){     /*      * ココ      */     printf("[%d]\n",i+1);     printf("ID : %d\n", ->id);     printf("NAME : %s\n", ->name);     free( ->name);     free( );   }   free(obj); } 長々とすみません。

  • 構造体内のポインタのポインタについて

    ポインタを理解するために以下のようなテストプログラムを作りました。 test.h --- typedef struct i_info{ int i_id; char i_name[64]; } I_INFO; typedef struct j_info{ int j_id; char j_name[64]; } J_INFO; typedef struct k_info{ int k_id; char k_name[64]; } K_INFO; typedef struct info{ int id; char name[64]; I_INFO iinfo; J_INFO *jinfo; K_INFO **kinfo; } INFO; --- test.c --- 1 #include <stdlib.h> 2 #include <stdio.h> 3 #include "./test.h" 4 5 int main(int argc, char **argv) 6 { 7 INFO info; 8 J_INFO j; 9 K_INFO k; 10 K_INFO *pk=NULL; 11 12 memset (&info,NULL,sizeof(info)); 13 memset (&j,NULL,sizeof(j)); 14 memset (&k,NULL,sizeof(k)); 15 16 info.id = 1; 17 memcpy(info.name,"***",3); 18 19 info.iinfo.i_id = 2; 20 memcpy(info.iinfo.i_name,"*i*",3); 21 22 info.jinfo = &j; 23 j.j_id = 3; 24 memcpy(j.j_name,"*j*",3); 25 26 info.kinfo = &pk; 27 pk= &k; 28 k.k_id = 4; 29 memcpy(k.k_name,"*k*",3); 30 31 printf( "%d\n",info.id); 32 printf( "%s\n",info.name); 33 printf( "%d\n",info.iinfo.i_id); 34 printf( "%s\n",info.iinfo.i_name); 35 printf( "%d\n",info.jinfo->j_id); 36 printf( "%s\n",info.jinfo->j_name); 37 /* 38 printf( "%d\n",info.kinfo->k_id); 39 printf( "%s\n",info.kinfo->k_name); 40 */ 41 } --- 38,39行目をコメントアウトするとコンパイルは通るのですが、 そのままだとコンパイルエラーになります。 なぜいけないのでしょうか?理由を教えてください。

  • 文字列配列をメンバにもつ構造体の,メモリ動的確保

    下に同様の質問があるのですが,やはり理解できません. 文字列配列をメンバにもつ構造体の,メモリを動的に確保をしたいのですが,うまくいきません. 具体的には以下のようです. 正しくはどのようにすればよいでしょうか.よろしくお願いします. typedef struct { char **boy; char **girl; } Name_class; int init_name_class(Name_class name_class, int n_boy, int n_girl) { int i; name_class.boy = (char**) malloc( n_boy * sizeof(char**) ); for(i=0; i<n_boy; i++) name_class.boy[i] = (char*) malloc( 32 * sizeof(char*) ); name_class.girl = (char**) malloc( n_girl * sizeof(char**) ); for(i=0; i<n_girl; i++) name_class.girl[i] = (char*) malloc( 32 * sizeof(char*) ); } main(int argc, char *argv[]) { int i, j, n_boy=3, n_girl=2; Name_class name_class; init_name_class(name_class, n_boy, n_girl); name_class.boy[0] = "yukio"; name_class.boy[1] = "hideaki"; name_class.boy[2] = "mitsuru"; name_class.girl[0] = "youko"; name_class.girl[1] = "chiharu"; printf("%s, %s, %s, %s, %s\n", name_class.boy[0], name_class.boy[1], name_class.boy[2], name_class.girl[0], name_class.girl[1]); }

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

    こんにちはです。 メモリの動的確保なのですが、 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言語の構造体のファイルへの書き込みについて

    C言語を勉強しているものです。構造体を指定した番号の場所にファイルへ書き出し、その指定した番号の場所の構造体をファイルから読み込み表示というプログラムを作成したいのですが、うまくいかずどうしたらいいのかわかりません。説明不足ですがご教授お願いします。 ソフトはVisual C++ 2008 Express Editionを使ってます。 ↓↓↓作成ソースコード↓↓↓ #include<stdio.h> #include<stdlib.h> struct S_data{ char Name[10+1];/*名前*/ int Sex;/*性別*/ int Height;/*身長*/ float Weight;/*体重*/ }; void main(){ FILE *Fp; int pos; int Ret; struct S_data tag; memset(&tag,'\0',sizeof(tag)); Fp=fopen("aaa.dat","r+b"); if(Fp==NULL){ Fp=fopen("aaa.dat","w+b"); if(Fp==NULL){ printf("File not open\n"); exit(2); } } while(1){ scanf("%d",&pos); /*番号の入力*/ if (pos==0) break; scanf("%s",tag.Name);/*名前*/ scanf("%d",&tag.Sex);/*性別*/ scanf("%d",&tag.Height);/*身長*/ scanf("%d",&tag.Weight);/*体重*/ fseek(Fp,sizeof(tag)*(pos),SEEK_SET); fwrite(&tag,sizeof(tag),1,Fp); memset(&tag,'\0',sizeof(tag)); } while(1){ scanf("%d",&pos); if (pos==0) break; fseek(Fp,sizeof(tag)*(pos),SEEK_SET); fread(&tag,sizeof(tag),1,Fp); printf("%s\n",tag.Name); printf("%d\n",&tag.Sex); printf("%d\n",&tag.Height); printf("%d\n",&tag.Weight); memset(&tag,'\0',sizeof(tag)); } Ret=fclose(Fp); if (Ret!=0){ exit(2); } }

  • 構造体のファイル書き込み&読み出しに関して2

    C言語を勉強しているものです。指定した番号に構造体を書き込み、指定した番号をの構造体を出力するプログラムを作成したいのですが、表示結果画像のようになってしまいます。 デバックしても、どこが違うのかがわかりません。説明不足かとは思いますがご教授お願いします。 ↓↓ソースコード↓↓ #include<stdio.h> #include<stdlib.h> struct S_data{ char Name[10+1];/*名前*/ int Sex;/*性別*/ int Height;/*身長*/ float Weight;/*体重*/ }; void FR_data(FILE *Fp,int pos); void FW_data(FILE *Fp,int pos); void OUP_data(struct S_data tag); void INP_data(struct S_data *tag); int RF_data(FILE *Fp,struct S_data *tag,int pos); int WF_data(FILE *Fp,struct S_data *tag,int pos); void main(){ FILE *Fp; int pos=0; int Ret; Fp=fopen("aaa.dat","r+b"); if(Fp==NULL){ Fp=fopen("aaa.dat","w+b"); if(Fp==NULL){ printf("File not open\n"); exit(2); } } while(1){ printf("入力の番号[0:終了]->"); scanf("%d",&pos); if(pos==0) break; FW_data(Fp,pos); } while(1){ printf("出力の番号[0:終了]->"); scanf("%d",&pos); if(pos==0) break; FR_data(Fp,pos); } Ret=fclose(Fp); } void FR_data(FILE *Fp,int pos){ struct S_data Temp; /*出力情報*/ int Ret; /*返却値*/ memset(&Temp,'\0',sizeof(Temp)); Ret=RF_data(Fp,&Temp,pos); /*情報の読み込み*/ if (Ret!=1){ printf("File not read\n"); }else{ OUP_data(Temp); /*情報の表示*/ } } void FW_data(FILE *Fp,int pos){ struct S_data wk; /*入力情報*/ int Ret; /*返却値*/ memset(&wk,'\0',sizeof(wk)); INP_data(&wk); /*情報の入力*/ Ret=WF_data(Fp,&wk,pos); /*情報の書き込み*/ if (Ret!=1){ printf("File not write\n"); } } void OUP_data(struct S_data tag){ printf("Name:%s\n",tag.Name); if (tag.Sex==0){ printf("Sex:M\n"); }else{ printf("Sex:F\n"); } printf("Height:%d\n",tag.Height); printf("Weight:%.2f\n",tag.Weight); } void INP_data(struct S_data *tag){ memset(tag,'\0',sizeof(tag)); printf("Name-->"); scanf("%s",&tag->Name); printf("Sex[0:M1:F]-->"); scanf("%d",&tag->Sex); printf("Height-->"); scanf("%d",&tag->Height); printf("Weight-->"); scanf("%f",&tag->Weight); } int RF_data(FILE *Fp,struct S_data *tag,int pos){ int Ret_I; /*fseek返却値*/ size_t Ret_S; /*fread返却値*/ Ret_I=fseek(Fp,sizeof(tag)*(pos),SEEK_SET); Ret_S=fread(tag,sizeof(tag),1,Fp); return Ret_S; } int WF_data(FILE *Fp,struct S_data *tag,int pos){ int Ret_I; /*fseek返却値*/ size_t Ret_S; /*fwrite返却値*/ Ret_I=fseek(Fp,sizeof(tag)*(pos),SEEK_SET); Ret_S=fwrite(tag,sizeof(tag),1,Fp); return Ret_S; }

  • 自己参照型構造体とソート

    現在C言語の自己参照型について勉強をして入るのですが mallocで確保した領域でソートを行うにはどのようにすれば 良いのでしょうか。 (qsort関数は使わず、独自の関数で行う) *図 -database |number |name |next----batabase _____________|number _____________|name _____________|next------と続く ソースコード #include <stdio.h> struct database{ int number; char f_name; struct *next; }; int data_sort(){ /* ここのやり方がWebを見ても理解が出来ない状態です。 */ } int main(){ struct database *d1,*d2; d1 = (struct database *)malloc(sizeof(struct database*)) d2 = NULL; while(cnt < 10){ scanf("%d",&d1->number); scanf("%s",d1->name); d1->next = d2; d2 = d1; cnt++; } data_sort(); }

  • VC++2005MFC 入れ子構造体の使い方

    VC++2005MFC typedef struct TMago{ stTestData mdata1[1000]; }stMago; typedef struct TKo{ stTestData kdata1[10000]; stTestData kdata2[10000]; stTestData kdata3[10000]; stTestData kdata4[10000]; stTestData kdata5[10000]; stMago *pMago[10000]; }stKo; typedef struct TOya{ stTestData odata1[100]; stTestData odata2[100]; stKo *pKo[100]; }stOya; stOya m_stOya;//メンバ変数 という構造体が定義されているのですが、 【Q1】 pMago、pKoのそれぞれ指定した分のメモリ確保は 例)それぞれ10個と20個分メモリ確保したい場合 for(int i = 0; i < 10; i++) { m_stOya.pKo[i] = new TOya; } とした後、 for(int i = 0; i < 10;i++) { for(int j = 0; j < 20; j++) { m_stOya.pKo[i]->pMago[j] = new TMago; } } で良いでしょうか? 【Q2】 また、これを解放するには、 同じループ処理を今度は内側から for(int i = 0; i < 10;i++) { for(int j = 0; j < 20; j++) { Delete m_stOya.pKo[i]->pMago[j]; } } for(int i = 0; i < 10; i++) { Delete m_stOya.pKo[i]; } で良いでしょうか? 【Q3】 pMago[0]の内容をpMago[1]へコピーしたい場合は memcpy(m_stOya.pKo[0]->pMago[1], m_stOya.pKo[0]->pMago[0], sizeof(TMago)); で良いでしょうか? 使い方なんてCの基本だろーですとか、そもそもこんな作りの構造体やめれば? と思われることは重々承知ですが、ご教授お願いいたしますm(__)m

  • 構造体についてです。

    typedef struct student{ int id; char name[20]; int kokugo; int sansu; int eigo; }STUDENT; と、 struct student{ int id; char name[20]; int kokugo; int sansu; int eigo; }; の違いはなんでしょう? 私は下記をよく使うのですが・・・。 typedefについて詳しく知りたいです。

専門家に質問してみよう