【问题标题】:C malloc struct implementation [closed]C malloc 结构实现
【发布时间】:2016-10-25 20:00:48
【问题描述】:

以下程序有问题。当我尝试编译它时,它崩溃了。我猜这是插入函数中某处的分段错误,但我就是不知道在哪里。

char *names[HOW_MANY]= {"Simon", "Suzie", "Alfred", "Chip", "John", "Tim",
          "Harriet"};
int ages[HOW_MANY]= {22, 24, 106, 6, 18, 32, 24};

struct person 
{
  char name[40];
  unsigned int age;
  struct person *next;
};

struct person* insert(struct person *people[], char *name, int age) 
{
  struct person *ptr;
  ptr=(struct person * )malloc(sizeof(struct person));
  if(ptr==NULL)
  {
    printf("error");
    return;
  }
  //ptr=ptr->next;
  strcpy(ptr->name,name);
  ptr->age = age;
  ptr->next=NULL;

}

int main() 
{
  struct person *people[HOW_MANY];
  for (int i =0; i<HOW_MANY;i++) 
      insert (people, names[i], ages[i]);

  for(int i=0;i<HOW_MANY;i++)
    printf("%s %d\n", people[i]->name, people[i]->age);
  return 0;
}

【问题讨论】:

  • 您是否使用调试器单步执行了代码?那应该告诉你哪条线路有故障。我注意到insert 实际上从未将ptr 放入people 数组中,我猜这是根本问题。
  • 您的代码中有相互冲突的目标。拥有next 成员会使您看起来想要一个人的链接列表,但您在main() 中声明了一个struct person 指针数组。你是想构造一个数组还是一个人的链表?
  • 结构人指针数组
  • 如果你想在insert()函数中处理一个数组,那么你需要传递你想修改的人的索引,比如i循环计数器变量和将people[i] 设置为等于您分配的person 对象。
  • 您收到了哪些编译器警告?您将函数定义为 struct person* insert(...) ...,但实际上并没有返回值 - 您只是从函数的底部跌落。

标签: c pointers struct malloc


【解决方案1】:

这是一个小改动,应该可以让您继续前进:

void insert(struct person **person_ptr, char *name, int age) 
{                      /* ^^^^^^^^^^^^ one person */
  struct person *ptr;
  ...
  ptr->next=NULL;
  *person_ptr = ptr;   /* send _ptr_ back to the calling code. */
}

int main() 
{
  struct person *people[HOW_MANY];
  for (int i =0; i<HOW_MANY;i++) 
      insert (&people[i], names[i], ages[i]);
           /* ^      ^^^ Just pass the one person you're interested in */
  ...
}

解释:**person_ptr 获取指针的地址 (&amp;people[i])。然后*person_ptr=... 将更改该值。所以效果是insert()(本质上)是*&amp;people[i]=ptr;,也就是说,people[i]=ptr;。您需要&amp;*,因为C 通过值而不是通过引用传递参数。

请注意,代码还存在一些其他问题。

  • 如果内存不足,insert() 的调用者不知道。你知道它是因为"error" 打印输出,但调用者应该知道它。
  • 正如@eddiem 指出的那样,如果您只使用数组,则不需要next
  • insert() 被声明为返回 struct person*,但从未分配或使用该返回值。 insert() 可以是 void insert() 或(表示成功或失败)bool insert()

【讨论】:

  • return( ptr ); 会容易得多。
  • @AndrewHenle 同意。我试图尽可能地坚持 OP 的逻辑,因此 **.
  • @cxw 函数应该返回一个值,或者声明为void返回类型
  • @M.M 完成! (填充物满足最小长度)
猜你喜欢
  • 1970-01-01
  • 2018-11-05
  • 2012-10-02
  • 2019-01-26
  • 2012-09-19
  • 2012-01-19
  • 2011-02-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多