C中结构中的动态结构数组

时间:2013-04-08 12:59:49

标签: c dynamic malloc structure

我对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;
}

我现在得到的错误是分段错误(核心转储)错误(在程序测试期间,而不是在编译期间)。我想我再次对指针做错了,但我真的不明白我做错了什么......有什么帮助吗?

3 个答案:

答案 0 :(得分:4)

您不能在与struct分开的结构中分配数组。相反,对于灵活的数组成员 * ,请执行以下操作:

将要分配的元素数量读入int,可能是一个名为nmax的元素(单独的int,而不是结构中的nmax成员)。

为整个结构和数组分配空间,并将该空间的地址分配给指针:

struct cap_profile *profile = malloc(sizeof *profile + nmax * sizeof *profile->arr);

* 灵活的数组成员是一个在结构末尾有未指定主要维度的数组。

答案 1 :(得分:1)

当您使用malloc(或类似函数)分配内存时,它会返回指针。您不能将此指针指定给数组。换句话说,一旦创建,就无法使数组指向其他内容。

你应该做的是将数组声明为指针。

答案 2 :(得分: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);
}

另外两点:

  1. 如果要在该函数之外使用其中的值,请分配cap_profile结构并从read_cap_profile()函数返回指向它的指针。
  2. 'for'循环应该具有&lt; profile-&gt; nmax,not&lt; =