内存泄漏链表

时间:2017-04-28 15:17:04

标签: c memory-management memory-leaks linked-list

我遇到了CS课程的作业问题。我一直在和朋友一起工作,我们发现我们的代码有内存泄漏,但是我们找不到问题所在。本质上,代码应该创建一个2-1000数字的链表。然后,代码使用deletemultiples来删除非素数的数字。它通过取一个数字并删除链表中该数字的任何倍数来实现。当我们使用valgrind时,它返回了内存泄漏。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

struct node{
    int info;
    struct node *next;
};

typedef struct node node;

node *inserthead(node *head, int a);
node *inserttail(node *head, int a);
node *deletemultiples(node *head, int a);
void printlist(node *head);
void freelist(node *head);

int main(){

    node *head1 = NULL;
    int i,j;
    for(i = 2;i <= 1000;i++)
        head1 = inserttail(head1,i);
    for(i = 2; i <= 32; i++){
        head1 = deletemultiples(head1,i);
    }
    printlist(head1);
    freelist(head1);
}

node *inserthead(node *head, int a){
    node *ptr;

    ptr = (node*)malloc(sizeof(node));
    ptr->info = a;
    ptr->next = head;

    return(ptr);
}

node *inserttail(node *head, int a){
    node *ptr;
    node *ptr2 = head;

    ptr = (node*)malloc(sizeof(node));
    ptr->info = a;
    ptr->next = NULL;

    if(head == NULL)
        return(ptr);
    else if (head->next == NULL){
        head->next = ptr;
        return(head);
    }
    while(head->next != NULL)
        head = head->next;

    head->next = ptr;
    return(ptr2);
}

void printlist(node *head){
    while(head!=NULL){
        printf("%i ",head->info);
        head = head->next;
    }
    printf("\n");
}

void freelist(node *head){
    node *ptr = head;
    while(head != NULL){
        head = head->next;
        free(ptr);
        ptr = head;
    }
}

node *deletemultiples(node *head, int a){
  node *ptr = head, *temp = head;

  while (ptr != NULL) {
      if(ptr->info % a > 0){
        ptr = ptr->next;
        temp = temp->next;
      }
      else{
        ptr = ptr->next;
        temp->next = ptr;
      }
    }

  return(head);

}

如果有人能帮我们弄清楚我们做错了什么,我们将不胜感激!

1 个答案:

答案 0 :(得分:2)

您的deletemultiples()函数永远不会释放它取消链接的节点,因此当freelist()遍历列表以删除它时,freelist()永远不会到达它们。删除删除的节点的方式与{{1}}中的删除节点相同。

或者,您可以创建一个包含1,000个节点的数组(这是将这样的常量转换为符号名称的好习惯。)并将该数组中的节点链接和取消链接作为弱引用。当你销毁所有依赖它的列表时,你可以在一次调用中释放整个数组。

在您的代码中寻找内存泄漏的荣誉。它会为你带来很多悲伤。