構造体の配列のアロケート方法とダブルポインタでの扱い方

このQ&Aのポイント
  • 構造体の配列をダブルポインタで返す関数を作成する方法や、アロケートの仕方について分からないという質問です。構造体の配列を作成するためのアロケート方法や、forループを使って配列を参照する方法を教えてください。
  • Webでの検索では求める情報が得られなかったため、こちらで質問させていただいています。例としてコードを提示しており、アロケートや配列の参照について具体的な説明を求めています。
  • 回答では、構造体の配列を作成する際のアロケート方法や、配列の参照方法について詳しく説明してください。また、ポインタやforループの基本的な使い方も合わせて教えていただけると助かります。
回答を見る
  • ベストアンサー

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

基本的な事かもしれないのですが、 構造体の配列をダブルポインタで返すような関数を作成したいのですが、アロケートの仕方と、そもそも配列をダブルポインタで扱う方法が良く分かってないのかもしれません。 どなたかご教授頂けないでしょうか? 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); } 長々とすみません。

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

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct member{ int id; char* name; } member_t; int get_result(member_t *pobj){ pobj->id = 100; pobj->name = strdup("nakayama"); return 0; } #define SIZE 10 int get_resultList(member_t **ppobj){ int i; char buff[32]; *ppobj=(member_t*)calloc(SIZE, sizeof(member_t)); for(i=0;i<SIZE;i++){ (*ppobj)[i].id=1000+i+1; sprintf(buff,"name%02d",i+1); (*ppobj)[i].name=strdup(buff); } return 0; } void main(){ member_t m; member_t *obj; int i; get_result(&m); printf("id:%d,name:%s\n", m.id, m.name); get_resultList(&obj); for(i=0;i<SIZE;i++){ printf("[%d]\n",i+1); printf("ID : %d\n", obj->id); printf("NAME : %s\n", obj->name); free(obj->name); // free(obj); obj++; } free(obj); }

関連するQ&A

  • 構造体について(配列)

    こんばんはです。 下記のように 例 typedef struct person{ char name[256]; char pass[256]; }mydata; mydata men[5]; と、言う具合にあったとします。 menには全て入力されていて、例えばmen[3].nameとpassを消去したいとします。 その際、strcpy(men[3].name,"")とかしてるのですが、結局は、men[3]にはNULLが入るだけで、クリアというわけにはいかないのです。 全部クリアはmemsetをつかってできるのですが、場所指定ではどのようにするのでしょうか? 最終的にはmen[2]をクリアしたら、men[3]以降をずらして格納したいと思ってます。 切り取ったりしたいですが、できるのでしょうか?その場合、配列数は減らないのでしょうか? 消去した場所にコピーという形でずらしていったらいいかもですが・・。 アドバイスいただけたらうれしいです。 よろしくおねがいいたします。

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

    ポインタを理解するために以下のようなテストプログラムを作りました。 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行目をコメントアウトするとコンパイルは通るのですが、 そのままだとコンパイルエラーになります。 なぜいけないのでしょうか?理由を教えてください。

  • C言語にて構造体のメンバがNULLであるかを判定するサンプルを作成して

    C言語にて構造体のメンバがNULLであるかを判定するサンプルを作成しています。 一応目的の動作はするのですが、プログラミングとして正しいか教えて頂ければと 思います。 <test.c> int main() { /* ---------------------------------------- */ /* 構造体のメンバ(NULL保障無し)がNULLか */ /* 比較するサンプル */ /* ---------------------------------------- */ char buf[50]; /* サンプル構造体 */ struct ST_test { int cd; char name[10]; int no; }; struct ST_test st_test; /* 構造体定義 */ memset(&st_test,0x00,sizeof(st_test)); /* 構造体初期化 */ memset(&buf[0],0x00,sizeof(buf)); /* 構造体初期化 */ /* 構造体に値セット */ st_test.cd = 12; memcpy(&st_test.name[0],"aabbccddee",sizeof(st_test.name)); st_test.no = 999; /* NULL判定 */ if(*st_test.name == 0x00) { printf("NULLです\n"); } else { printf("NULLではないです\n"); } return (0); }

  • 動的に生成した文字列の配列を返す関数について

    動的に生成した文字列の配列を返す関数について お世話になります。 動的に文字列の配列を生成する関数を作ったのですが、 配列をうまく受け渡すことができず困っています。 以下のように入力された件数の数だけ "abc 0"~"abc n"という文字列を生成を行っています。 関数自体は期待通りの動作をしているようなのですが、 (Test1関数の最後でbfを確認しました) 呼び出し側にうまく配列を渡すことができません。 以下にソースを掲載いたしますのでどなたかご教示いただけたらと思います。 環境はVisualStudio2005です。 よろしくお願いします。 #include <stdio.h> #include <string.h> #include <stdlib.h> void Test1(char **bf, int *cnt) { int i; int kensu; int charlength; char num[10]; char **nm1 = NULL; char **nm2 = NULL; printf("件数を入力:"); scanf("%d",&kensu); for(i=0; i < kensu; i++) { nm2 = (char**)realloc(nm1, sizeof(char*) * (i + 1)); nm1 = nm2; charlength=128; nm1[i] = (char*)malloc(sizeof(char) * (charlength)); strcpy(nm1[i], "abc "); itoa(i, num, 10); strcat(nm1[i], num); } bf = nm1; *cnt = i; return ; } void main() { int cnt; char **bf = NULL; Test1(bf, &cnt); printf("START\n"); printf("全部で%d件。\n", cnt); for(int i=0;i < cnt;i++) { printf("%s\n",bf[i]); } free(bf); printf("END\n"); }

  • C言語 構造体(2)

    ご質問です。 構造体で、あらかじめメンバ数を固定したものではなく、 テキストファイルを読み込んだときにメンバ数を変えて読み込みたいのです。 (カンマできりたい) aaa.txt ------------------------ あああ,いいい ------------------------ となっているときは、 tmp.nm[0]=あああ tmp.nm[1]=いいい となり、 kamoku.nm[0] kamoku.nm[1] をprintf。 aaa.txt --------------------------- あああ,いいい,ううう,えええ --------------------------- の場合は tmp.nm[0]=あああ tmp.nm[1]=いいい tmp.nm[2]=ううう tmp.nm[3]=えええ kamoku.nm[0] kamoku.nm[1] kamoku.nm[2] kamoku.nm[3] をprintf。 下記は動きません。。 よろしくお願いいたします。 #include <stdio.h> struct kamokumei { char nm[10]; }kamoku; int main(void) { int i,P,t; FILE *fp; struct kamokumei kamoku[20]; char buf[1024]; fp = fopen("aaa.txt", "r"); P=3; t=0; while( fgets(buf, sizeof(buf), fp) ){ struct kamokumei tmp; sscanf(buf, "%s", tmp.nm[t]); nm[t++] = tmp; } for(i = 0; i < P; i++) { printf("%s\n", kamoku.nm[i]); } return 0; }

  • 構造体の配列について

    --------------------------------------------------- #include<stdio.h> #include<string.h> struct person{ char name[80]; int height; int weight; }; int main() { struct person dt[10]; strcpy(dt[1].name,"日本太郎");    //// (1) //// dt[1].weight=70; dt[1].height=180; dt[5]=dt[1];    //// (2) //// printf("%s %d %d \n",dt[1].name,dt[1].weight,dt[1].height); return 0; } ----------------------------------------------------- 以上のプログラムは参考書に記述されていたものですが、(1)の部分で、配列名dtに「"日本太郎"」を設定するならわかるのですが、配列の1つの要素「dt[1]」に「"日本太郎"」を設定しているというように見え、これはエラーが出ると感じたのですが出ません。 char dt[10]; strcpy(dt[1],"日本太郎"); 以上のようにしてしまっているというイメージがあります。 後、(2)の部分もよくイメージがわきません。 以上、どのような仕組みになっているのか教えていただければ嬉しいです。

  • 構造体配列

    いつもお世話になっています。 今日構造体配列を勉強した際に下の演習をしていたのですが、いまいち基礎的な関数や配列のことやコマンドライン引数のことが理解できていません。一応自分なりにプログラムを書いてみたのですが、エラーがでます。 どなたかアドバイス・ご指摘・解説・例などをおねがいいたします。 問題はコマンドライン引数で人数を指定し,人数分のデータを標準入力(キーボード)から構造体配列に入力し,標準出力(ディスプレイ)に出力するプログラムです。 #include<stdio.h> typedef struct{ char name[100]; int age; double height; double weight; } PERSONAL_DATA1; typedef struct{ int person[10]; }PERSONAL_DATA2; PERSONAL_DATA1 input_personal_data(int num); void output_personal_data(PERSONAL_DATA2 person[10],int num); int main(int argc, char *argv[]){ PERSONAL_DATA1 x; int num,i; char person[10]; if(argc != 2){ printf("Usage ./test number"); return 0; } num=atoi(argv[1]); for(i=0;i<10&&i<num;i++){ person[i]=input_personal_data(); output_personal_data(person,num); return 0; } } PERSONAL_DATA input_personal_data(void){ PERSONAL_DATA1 x; printf("name>"); scanf("%c" ,&x.name); printf("age>"); scanf("%d" ,&x.age); printf("height>"); scanf("%lf" ,&x.height); printf("weight>"); scanf("%lf" ,&x.weight); return x; } void output_personal_data(PERSONAL_DATA2 person[10],int num){ PERSONAL_DATA1 x; printf("name>>%s\n" ,x.name); printf("age>>%d\n" ,x.age); printf("height>>%lf[cm]\n" ,x.height); printf("weight>>%lf[kg]\n" ,x.weight); } またコマンドライン引数で指定したデータファイルAから入力した個人データ集合を構造体配列に取り込み,標準出力(ディスプレイ)と同じくコマンドライン引数で指定したデータファイルBへファイル出力に出力するプログラムというおまけの問題もあります。 こちらの問題のヒントもいただけませんか?

  • 配列から構造体へデータコピー

    配列から構造体へデータのコピーをしたいのですが、 構造体のメンバがビットフィールドで構成されている時の処理がわかりません。 --------test.c----------- #include <stdio.h> #include <string.h> typedef struct{ unsigned char aaa :1; unsigned char bbb :1; unsigned char ccc :1; unsigned int ddd :13; unsigned char eee :2; unsigned char fff :2; unsigned char ggg :4; }test_t; int main(void) { test_t test_t; unsigned char data[]={0x5F, 0xFE, 0x1C}; memcpy(&test_t, data, 4); printf("aaa = %X\n", test_t.aaa); printf("bbb = %X\n", test_t.bbb); printf("ccc = %X\n", test_t.ccc); printf("ddd = %d\n", test_t.ddd); printf("eee = %X\n", test_t.eee); printf("fff = %X\n", test_t.fff); printf("ggg = %X\n", test_t.ggg); return 0; } ------期待出力--------- aaa = 0 bbb = 1 ccc = 0 ddd = 1FFE eee = 0 fff = 1 ggg = 12 「test.c」を実行した時に「期待出力」のような出力を期待していたのですが、実際には aaa = 1 bbb = 1 ccc = 1 ddd = 1 eee = 0 fff = 0 ggg = 0 と表示されてしまいます。 ビットフィールドで構成された構造体に、配列の値をそのままあてる事は出来ないのでしょうか? 出来るだけ、マスクやシフト演算を使用しないで、配列からビット単位で値を抽出したいのですが・・・

  • メモリとポインタと配列と

    malloc()を使用して可変の変数を作り加工。 後々に参照するためにポインタの配列に格納したいと考えております。 malloc()を行った後は必ずfree()にてメモリを開放せねばなりませんが、開放するとポインタの配列に格納した値も消えてしまいます。 だからといって開放せずにいるとメモリリークが起きてしまいます。 この様な場合はどのようにすればよろしいのでしょうか? 大体以下のような処理を考えております。 ご教授願えれば幸いです。 ****************************************   char *p[100];   for(int i=0;i<100;i++) {     char *word1 = "あいう";// ここでは固定文字を代入しているが、実際には何桁の文字列が入るかは不明。     int size = strlen(word1) + 1;     char *memo1 = (char *)malloc(size);     if (memo1 == NULL) {       printf("メモリを割り当てられません\n");       exit(1);     }     strcpy(memo1, word1);          //・     //・ *memo1 を利用した処理。     //・     char *word2 = "abc";// ここでは固定文字を代入しているが、実際には何桁の文字列が入るかは不明。     size = strlen(word1) + 1 + strlen(word2) +1;     char *memo2 = (char *)malloc(size);     if (memo2 == NULL) {       printf("メモリを割り当てられません\n");       exit(1);     }     memset(memo2, 0x00, size); //初期化     strcpy(memo2, word2);     strcat(memo2, "\t");     strcat(memo2, memo1);     p[i] = NULL;     p[i] = memo2;     free(memo2);     free(memo1);   } **************************************** 宜しくお願いします。

  • 構造体で配列を使用しない方法。

    構造体で配列を使用せずに、メモリ領域を獲得する関数を使用する場合はどうすればよろしいですか??  例 char *str; struct seiseki{ char name[20]; int eig; int suu; int kok; char rank[3]; }; str = ()malloc();

専門家に質問してみよう