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

4

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

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

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

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

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

于 2013-04-08T13:08:56.280 回答
1

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

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

于 2013-04-08T13:02:45.260 回答
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' 循环应该有 <profile->nmax,而不是 <=
于 2013-04-08T14:28:18.693 回答