0

私は C プログラミングにまったく慣れていないので、いくつかのトリッキーな問題に出くわしました。私がやりたいことは、C の別の構造体で動的構造体配列を定義することです。

これが私のコードです: まず、構造の形状を定義します:

struct cap_prof_arrays
   {
   double zarr;
   double profil;
   double sx;
   double sy;
   double d_arr;
   };

struct cap_profile
   {
   int nmax;
   double rtot1;
   double rtot2;
   double cl;
   double binsize;
   struct cap_prof_arrays arr[]; /*Will get proper size allocated to it later*/
   };

void read_cap_profile(struct inp_file cap) /* I defined the inp_file structure cap before, everything works great on that account */
   {
    FILE *fptr;
    int i, n_tmp;
    struct cap_profile profile;

    fptr = fopen(cap.prf,"r");
    fscanf(fptr,"%d",&profile.nmax);
    // Increase structure array sizes to fit demands
    profile.arr = malloc(sizeof(struct cap_profile)+profile.nmax*sizeof(double));
    //continue reading data
    for(i=0; i<=profile.nmax; i++){
      fscanf(fptr,"%lf %lf",&profile.arr[i].zarr,&profile.arr[i].profil);
      }
    fclose(fptr);

    //rest of program

さて、主な問題は、コンパイル中に、何をしようとしても、メモリ割り当てを実行しようとする行でエラーが発生することです。あなたの誰かが私を助けることができるかどうか疑問に思っていましたか?構造体の宣言中に非常に大きな配列サイズを定義するだけで、おそらく私の人生をずっと楽にすることができると思いますが、動的なサイズ設定でそれをやりたいと思っています. だから私はあなたが私を助けてくれることを願っています:)

どうもありがとう!

EDIT1: ここで得た回答に基づいていくつか変更しました。これは私のプログラムが今どのように見えるかです:

struct cap_prof_arrays
  {
  double zarr;
  double profil;
  double sx;
  double sy;
  double d_arr;
  };

struct cap_profile
  {
  int nmax;
  double rtot1;
  double rtot2;
  double cl;
  double binsize;
  struct cap_prof_arrays *arr; /* will get proper size allocated to it later */
  };

struct cap_profile read_cap_profile(struct inp_file cap)
{
 FILE *fptr;
 int i, n_tmp;
// struct cap_profile profile;

 printf("Reading capillary profiles...\n");
 fptr = fopen(cap.prf,"r"); /* READING THE CAPILLARY PROFILE */
 if(fptr == NULL){
   printf("%s file does not exist.\n",cap.prf);
   exit(0);
   }
 fscanf(fptr,"%d",&n_tmp);
 // increase structure array sizes to fit demands;
 struct cap_profile *profile = malloc(sizeof(*profile)+(n_tmp+1)*sizeof(*profile->arr));
 profile->nmax = n_tmp;
 // continue reading the data;
 for(i=0; i<=profile->nmax; i++){
   fscanf(fptr,"%lf %lf",&profile->arr[i].zarr,&profile->arr[i].profil);
   }
 fclose(fptr);

 n_tmp = profile->nmax;

 fptr = fopen(cap.axs,"r"); /* READING THE AXIS DEFINITION FILE */
 if(fptr == NULL){
   printf("%s file does not exist.\n",cap.axs);
   exit(0);
   }
 fscanf(fptr,"%d",&profile->nmax);
 if(profile->nmax != n_tmp){
   printf("Inconsistent axis.dat file: number of intervals different.\n");
   exit(0);
   }
 for(i=0; i<=profile->nmax; i++)
   fscanf(fptr,"%lf %lf %lf",&profile->arr[i].zarr,&profile->arr[i].sx,&profile->arr[i].sy);
 fclose(fptr);

 fptr = fopen(cap.out,"r"); /* READING THE OUTER PROFILE */
 if(fptr == NULL){
   printf("%s file does not exist.\n",cap.out);
   exit(0);
   }
 for(i=0; i<=profile->nmax; i++)
   fscanf(fptr,"%lf %lf",&profile->arr[i].zarr,&profile->arr[i].d_arr);
 fclose(fptr);

 profile->rtot1 = profile->arr[0].d_arr;
 profile->rtot2 = profile->arr[profile->nmax].d_arr;
 profile->cl = profile->arr[profile->nmax].zarr;
 cap.d_screen = cap.d_screen + cap.d_source + profile->cl;
 profile->binsize = 20.e-4;

 return *profile;
}

私が今得たエラーは、セグメンテーション違反(コアダンプ)エラーです(コンパイル時ではなく、プログラムのテスト中)。私はポインタで何か間違ったことをしていると思いますが、私が間違っていることを本当に理解していません.何か助けはありますか?

4

3 に答える 3

0

あなたはこのようにすることができます:

struct cap_profile {
  int nmax;
  struct cap_prof_arrays **arr;
};

そして、次のように割り当てます。

struct cap_profile *profile = calloc(1, sizeof(*profile));

fscanf(fptr, "%d", profile->nmax);
profile->arr = calloc(1, profile->nmax * sizeof(*(profile->arr)));
for (i = 0; i < profile->nmax; i++) {
  profile->arr[i] = calloc(1, sizeof(*(profile->arr[i])));
  fscanf(fptr, "%lf %lf", &profile->arr[i]->zarr, &profile->arr[i]->profil);
}

その他の 2 つのポイント:

  1. cap_profile 構造体を割り当て、read_cap_profile() 関数の外部で値を使用する場合は、その構造体へのポインターを返します。
  2. 「for」ループには、<= ではなく、< profile->nmax を指定する必要があります
于 2013-04-08T14:28:18.693 に答える