动态分配的结构数组

时间:2012-03-08 02:09:29

标签: c memory struct malloc

我一直在努力让这个功能正常工作。这是作业:

  

添加:请求零件名称,价格和数量。将信息保存到动态分配的结构数组中。您可以一次为最多3个结构分配空间。您需要根据需要动态创建更多内存。使用此结构(如果需要,可以使用typedef):

到目前为止,我的代码是

typedef struct  {
    char* name;
    float price;
    int quantity;
}part;


void add(part *item, int *part_count)
{
     //char temp[100];

     if (!item){
       item = malloc(sizeof(part)*3);
     }
     else{
      item = realloc(item, sizeof(part) * ((*part_count*3) + 1));
     }

     item[*part_count].name = malloc(sizeof(char)*64); // max of 64 characters

     printf("Please enter item name: \n");
     //fgets(temp, strlen(temp), stdin);
     //sscanf(temp, "%s", item[*part_count].name);
     scanf("%64s", item[*part_count].name);

     printf("Please enter item price: \n");
     //fgets(temp, strlen(temp), stdin);
     //sscanf(temp, "%f", &item[*part_count].price);
     scanf("%f", &item[*part_count].price);

     printf("Please enter item quantity: \n");
     //fgets(temp, strlen(temp), stdin);
     //sscanf(temp, "%d", &item[*part_count].quantity);
     scanf("%d", &item[*part_count].quantity);

     *part_count = *part_count+ 1;
  }

我曾尝试使用fgets()sscanf()获取输入,但使用该代码时,它永远不允许用户输入数据然后结束该功能。

我认为问题在于我的内存分配,因为当我尝试对数组执行任何操作时会出现分段错误,例如打印内容。

2 个答案:

答案 0 :(得分:1)

据推测,第一次调用add()时,item将为NULL,并且您将进行初始分配;后续调用realloc,以便数组大小是所需大小的3倍(我认为这不是你真正想要的)。

但是匹配项的参数不会因调用add()而改变,所以它保持为NULL,并且每次调用add()就好像它是初始调用一样,为3个结构分配空间(当您添加第4个结构时,这将是一个问题。)

您可以将项目设为**部分,并在当前使用部分的任何地方使用*部分,以便保留指针的新值(您将传递*部分的地址作为参数)。或者使用item的新值作为函数的返回值,这是一个更清洁的恕我直言。 (这是参考参数派上用场的地方,但C没有这样的东西。)

答案 1 :(得分:1)

您的功能有一个不可能的界面。它接受part *指针。该指针按值进入函数。在您mallocrealloc来电中分配给它的功能中。但调用者不会看到此更新值。当函数返回时,您分配的内存已泄漏,调用者具有原始指针值(可能为null)。

此外,最好使用结构封装动态数组。你有这个“部件计数”变量,它本身就是松散的,必须与数组一起传递到任何地方以跟踪它的大小。如何将它们包装在一起:

typedef struct part_list {
  struct part *part;
  int count;
} part_list;

现在有一个初始化空零件清单的功能。每个想要使用其他part_list函数的人都必须调用此

void part_list_init(part_list *pl)
{
  pl->part = 0;
  pl->count = 0;
}

然后编写你的功能来添加部件。

int part_list_add(part_list *pl)
{
  part_list *p;
  int index = pl->count++; /*  increment count, keep old value */

  /* realloc accepts a null pointer and then behaves like malloc */
  p = realloc(pl->part, sizeof *pl->part * pl->count);
  if (p == 0)
    return 0; /* failed to allocate/extend array */
  p1->part = p;

  if ((pl->part[index].name = malloc(64)) == 0) {
    pl->count = index; /* roll back the count: we didn't really allocate this part */
    return 0;
  }

  /* your code, updated with pl-> access */
  printf("Please enter item name: \n");
  scanf("%63s", pl->part[index].name); /* 63s not 64s!!! One byte for NUL char! */

  printf("Please enter item price: \n");
  scanf("%f", &pl->part[index].price); /* check the return value of scanf!!! */

  printf("Please enter item quantity: \n");
  scanf("%d", &pl->part[index].quantity);

  return 1; /* 1 means success */
}