为什么使用free()会导致无限循环

时间:2016-07-09 11:03:17

标签: c pointers linked-list free

当我运行以下代码时,它会给我一个无限循环的结果。但是,如果我注释掉insert函数中的空闲指针行,即free(ptr)free(ptrnext),那么它可以正常工作。任何人都能解释为什么会这样吗?

我很确定print和takeInput工作正常,因此可以忽略。

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

typedef struct Nodes{
    struct Nodes * next;
    int val;
}Node; 

//Function to create a linked list
Node * takeInput(){
    int data;
    Node *start =NULL ;
    Node *tail=NULL;

    printf("Enter the number of nodes"); 
    int num,i;
    scanf("%d",&num);
    for(i=1;i<=num;i++){
        if(start==NULL){
            start=malloc(sizeof(Node));
            puts("Enter data");
            scanf("%d",&data);
            start->val=data;
            start->next=NULL;
            tail=start;
        }
        else{
            Node * ptr = malloc(sizeof(Node));
            puts("Enter data" );
            scanf("%d",&data);
            ptr->val=data;
            tail->next=ptr;
            tail=tail->next;
        }   

    }   
    tail->next=NULL;        
    return start;
}

//Function to print
void print(Node * head){
    Node*ptr=head;
    while(ptr!=NULL){
        printf("%d->",ptr->val);
        ptr=ptr->next;
    }
}

//Function to insert a node in given linked list 
Node * insert(Node *start){
    int i,data;

    puts("Enter pos");
    scanf("%d",&i);

    puts("Enter data");
    scanf("%d",&data);

    Node * ptr=malloc(sizeof(Node));    
    ptr->val=data;
    ptr->next=NULL;

    if(i==1){

        ptr->next=start;
        start=ptr;

        free(ptr);  

    }
    else{
        Node * ptrnext=start;
        while(i!=1){
            ptrnext=ptrnext->next;
            i--;
        }

        ptr->next=ptrnext->next;
        ptrnext->next=ptr;

        free(ptr);
        free(ptrnext);

    }
    return start;
}

int main(void){
    Node * start =takeInput();  
    start=insert(start);
    print(start);
}

1 个答案:

答案 0 :(得分:1)

  

当我运行以下代码时,它会给我一个无限循环的结果。但是,如果我注释掉插入函数中的空闲指针行,即free(ptr)free(ptrnext),那么它可以正常工作。

  • 这是未定义的行为(当您不评论free()功能时)

  • 一旦你释放了记忆,你必须记住不再使用它。

  

注意:指针在释放后可能会或可能不会指向同一个块,它的未定义的行为

  • 所以除非你想要destroydelete节点,否则不要释放指针。

  • 因此,请勿使用free()函数中的insert,因为您没有删除任何节点。

  • 除此之外,我还没有看到在程序结束时解除分配内存的任何功能。

  • 始终确保使用delete()功能取消分配最终分配的内存

  • 以下是delete功能

    的典型实现
    void delete(Node* start)
    {
         Node* temporary = NULL;
         while(start != NULL)
         {
             temporary = start->next; //saving next node address
             free(start); //freeing current node
             start = temporary; //assigning start with next node address
         }
    
         printf("successfully destroyed the list!"); //function exit message
    }
    
  • main()功能结束时或当您希望delete整个列表

  • 时调用它