【问题标题】:dynamically allocated array of structs动态分配的结构数组
【发布时间】:2012-03-25 14:26:07
【问题描述】:

我已经尝试了好几个小时才能让这个功能正常工作。这是作业:

添加:请求零件名称、价格和数量。将信息保存到动态分配的结构数组中。您一次最多可以为 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() 进行输入,但使用该代码时,它不允许用户输入数据然后结束函数。

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

【问题讨论】:

  • 您在哪条线路上遇到了段错误?
  • 你如何计算part_count?如果是元素的数量,则无法访问该元素。因此,如果您的数组大小为10,则无法访问array[10]
  • 我不确定哪一行出现了段错误,但我有一个单独的打印功能,当我运行它时它会出现段错误。我以前问过,但显然我的打印功能不是问题。 part_count 也从 0 开始,每次调用 add 时递增。
  • 如何检查 seg 故障的位置?
  • @TristanPearce:你可以使用 gdb。这是short tutorial

标签: c memory struct malloc


【解决方案1】:

大概,当你第一次调用 add() 时,item 会是 NULL,你会做它的初始分配;随后调用 realloc 以使数组大小是所需大小的 3 倍(我认为这不是您真正想要的)。

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

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

【讨论】:

  • 我收到错误:在非结构中请求成员“名称”。这是在我将项目结构更改为 part** 类型,然后在函数调用中也对其进行更改之后。
【解决方案2】:

你的函数有一个不可能的接口。它接受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 */
}

【讨论】:

  • 我无法使用链表来解决问题,看起来你就是这样做的。
  • 这里提示的数据表示不是链表。有一个 part_list 包含一个指向数组的指针。 part_list 结构封装了数组和大小,使它们易于作为一个单元传递。 part_list_add 函数可以通过更新给定结构中的指针轻松分配和扩展数组。
猜你喜欢
  • 2019-07-19
  • 2020-03-06
  • 2021-10-30
  • 2017-03-30
  • 1970-01-01
  • 2011-12-13
相关资源
最近更新 更多