【課題8−2】

 

(プログラム例)

#include <stdio.h>
#define NRECORDS 10

typedef struct data_record {  /* RECORD型構造体の定義 */

         int id;

         char unit[10];

         long length;

         double *data;

} RECORD;

 

RECORD *create_record(void);

void free_record(RECORD *rec);

 

int main(void) {

         RECORD *tbl[NRECORDS]; /* RECORD型構造体へのポインタの配列tblを宣言 */

         int i;

 

         for (i = 0; i < NRECORDS; i++)  /* tblの各要素をNULLで初期化 */

                 tbl[i] = NULL;

 

         for (i = 0; i < NRECORDS; i++) {

         /* 関数create_recordが作成したRECORD型オブジェクトへのポインタをtblの各要素に受け取る */

                 if ((tbl[i]=create_record())==NULL) {

                          printf("Failed to create new record.\n");

                          goto FREE;

                 }

         };

        

         for (i = 0; i < NRECORDS; i++) {

         /* tblの各要素(ポインタ)が指すRECORD型オブジェクトの中身を表示 */

                 printf("ID    : %d\n", tbl[i]->id);

                 printf("unit  : %s\n", tbl[i]->unit);

                 printf("length: %d\n", tbl[i]->length);

                 printf("address of data: %p\n", tbl[i]->data);

         }

 

FREE:   for (i = 0; i < NRECORDS; i++) /* 各構造体オブジェクトのメモリを解放 */

                 free_record(tbl[i]);

         return 0;

}

 

/* 新しいRECORD型構造体オブジェクトを動的に生成する関数 */

/* 生成した構造体オブジェクトへのポインタを返す */

RECORD *create_record(void) {

         RECORD *rec;

 

         /* 新しいRECORD型構造体オブジェクトのためのメモリを確保 */

         if ((rec=(RECORD *)malloc(sizeof(RECORD)))==NULL) {

                 return NULL;

         }

         printf("Input data ID: ");

         scanf("%d", &(rec->id));

         printf("Input unit: ");

         scanf("%9s", rec->unit);

         printf("Input data length: ");

         scanf("%d", &(rec->length));

 

         /* 入力で指定された長さのdouble型配列のためのメモリを確保 */

         /* 失敗したら確保した構造体オブジェクトのメモリを解放後、NULLを返す */

         if ((rec->data=(double *)malloc(rec->length * sizeof(double)))==NULL) {

                 free(rec);

                 return NULL;

         }

 

         return rec;

}

 

/* RECORD型構造体オブジェクトのメモリを解放する関数 */

/* 引数がNULLポインタのときは何もしない */

void free_record(RECORD *rec) {

         if (rec!=NULL) {       /* 実体のある構造体オブジェクトを指してるポインタなら... */

                 free(rec->data);       /* メンバdataのメモリの解放 */

                 free(rec);              /* 構造体オブジェクトのメモリを解放 */

         }

}