C -Malloc无法在队列中为结构创造空间



我尝试创建一个包含2个int值的队列。问题发生在插入功能中。当我尝试分配内存时 -> Front->下一个程序停止。该错误仅在插入功能中发生。

struct Patient{
   int national_id;
   int condition;
};
struct Node{
   struct Patient *info;
   struct Node *next;
};
struct Queue{
   int total;
   struct Node *rear;
   struct Node *front;
   int insert_number;
};
void insert (struct Queue *head, int natid, int cond);
void pop_min(struct Queue *head);
struct Queue *create_queue(void);
void destroy_queue(struct Queue *head);
void read_file(struct Queue *head);
void print_natid(struct Node *node);
void pop_all_elements(struct Queue *head);
void main(){
   struct Queue *head;
   head=create_queue();
   read_file(head);
   pop_all_elements(head);
   destroy_queue(head);
}
struct Queue *create_queue(void){
   struct Queue *head =(struct Queue*) malloc(sizeof(struct Queue));
   head->total=0;
   head->insert_number=0;
   return head;
}
void print_natid(struct Node *node){
   printf("%d ",node->info->national_id);
}

void insert (struct Queue *head,int natid, int cond){
   if(head->total==0){
      head->front=(struct Node*)malloc(sizeof(struct Node));
      head->front->info->national_id=natid;
      head->front->info->condition=cond;
      head->rear=head->front;
   }
   else{
      head->front->next=(struct Node*)malloc(sizeof(struct Node));
      head->front->next->info->national_id=natid;
      head->front->next->info->condition=cond;
      head->front=head->front->next;
   }

   head->insert_number++;
   head->total++;
   if(head->insert_number==3){
      pop_min(head);
      head->insert_number=0;
   }
   print_natid(head->rear);
}
void pop_min(struct Queue *head){
   printf("%d ",head->rear->info->national_id);
   struct Node *temp=head->rear;
   head->rear=head->rear->next;
   free(head->rear);
   free(temp);
}
void destroy_queue(struct Queue *head){
   free(head);
}
void pop_all_elements(struct Queue *head){
   struct Node *temp;
   while(head->rear!=head->front){
      print_natid(head->rear);
      temp=head->rear;
      free(temp);
      head->rear=head->rear->next;
   }
   print_natid(head->rear);
   free(head->rear);
}
void read_file(struct Queue *head){
   FILE *fp;
   int natid;
   int cond;
   fp=fopen("patients.txt","r");
   while (fscanf(fp,"%d %d", &natid, &cond) ==2)
      insert(head,natid,cond);
   fclose(fp);
}

我在您的代码中看到以下问题:

问题1

insert()中,您尚未为新分配的Nodeinfo分配内存,然后再设置值。

您也没有在insert中设置新构建节点的nextrear->next保持非专业化。如果以后访问该指针,您将遇到未定义的行为。

我将更改以下代码以解决上述问题并减少重复代码。

您的代码:

if(head->total==0){
   head->front=(struct Node*)malloc(sizeof(struct Node));
   head->front->info->national_id=natid;
   head->front->info->condition=cond;
   head->rear=head->front;
}
else{
   head->front->next=(struct Node*)malloc(sizeof(struct Node));
   head->front->next->info->national_id=natid;
   head->front->next->info->condition=cond;
   head->front=head->front->next;
}

我的建议:

struct Node* node = malloc(sizeof(struct Node));
node->next = NULL;
node->info = malloc(sizeof(struct Patient));
node->info->national_id=natid;
node->info->condition=cond;
if(head->total==0){
   head->front = node;
   head->rear = node;
}
else{
   head->front->next = node;
   head->front = node;
}

问题2

您在pop_min中还需要拨打free

// This is wrong.
// Not only do you not need this but also it causes
// problems later when you try to use head->rear.
free(head->rear);

问题3

pop_all_elements中的以下行是一个问题。

  temp=head->rear;
  free(temp);
  // PROBLEM
  // Here you are trying to access memory that just got free'd in
  // previous line.
  head->rear=head->rear->next;

您需要交换最后两行。使用:

  temp=head->rear;
  head->rear=head->rear->next;
  free(temp);

我认为您需要添加其他部分 -

(head->front->next).info=(struct Patient *)malloc(sizeof(struct Patient));

当我尝试将内存分配为HEAD-> FRONT->下一个程序停止时。该错误仅在插入功能中发生。

实际上,如果该错误发生在malloc()内部,则是记忆损坏问题的征兆,其真正的位置可能在其他地方。一个候选人将是pop_all_elements()的错误代码:

while(head->rear!=head->front){
    print_natid(head->rear);
    temp=head->rear;
    free(temp);
    head->rear=head->rear->next;
}

评估head->rear->next时,它将释放一个释放内存的指针。通过将free(temp)移动到循环主体的末端来解决这一点。

另一个候选人是pop_min()

   struct Node *temp=head->rear;
   head->rear=head->rear->next;
   free(head->rear);
   free(temp);

观察到您不仅可以释放旧的rear,还可以释放 new rear,使head->rear留下无效的指针(如果该程序持续了很多时间,您很可能会在以后再免费获得)。该功能有时由insert()调用,因此可能会引起对insert()重复调用的问题,例如函数read_file()执行。

其他候选人包括此代码,该代码出现在您的插入功能的两个分支中:

    head->front->info->national_id=natid;
    head->front->info->condition=cond;

在任何情况下,您都不会将值分配给head->front->info,因此这两个作业产生了不确定的行为,这绝对可以表现为内存腐败。您可以考虑通过将Node.info的类型从struct Patient *更改为struct Patient(在其他地方进行相应的更改)来考虑解决该问题;除其他事项外,当您排出节点时,这也可以减轻您的任何需要 free 动态分配的Patient s。

但是,另一种可能性是malloc()工作正常,但是head->front是无效或无效的指针,因此分配给head->front->next会产生不确定的行为(表现为内存访问违规和伴随的停止)。我不太了解这将是如何发生的,但是鉴于您有几个与指针有关的问题,这是可以想象的。

当我使用它时,我观察到您的措施显然是针对将队列限制为两个要素的措施。此代码...

head->insert_number++;
head->total++;
if(head->insert_number==3){
    pop_min(head);
    head->insert_number=0;
}

...每三个居民都会脱离一个元素,但是如果在任何情况下(否则)脱水之前被四个或更多元素出现,则随后,队列将包含两个以上的元素。此外,当您排出元素时,您不会更新insert_numbertotal,因此仅包含有关插入多少元素的信息。特别注意,insert()取决于total来确定队列是否为空,如果在任何元素被征用后排空,则该测试将产生错误的结果。

相关内容

  • 没有找到相关文章

最新更新