Two functions, one is to create a link list, the other is to free the link list. If the Create function return a double pointer to the head node, use this node to free the link list, will encounter a segment error. But if changing the Create function to return a pointer to head node, then free the list, this will be OK.

Anyone who can explain this for me? Here is the code which have the segment errors:

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

typedef struct ListNode{
    int m_nValue;
    ListNode* m_pNext;
}ListNode;

ListNode** CreateList(int data[], int length){
   if(length<=0 || data == NULL)
       return NULL;
   ListNode *pHead = (ListNode*)malloc(sizeof(ListNode));
   ListNode *pNode = pHead;
   pNode->m_pNext = NULL;
   pNode->m_nValue = data[0];
   int i=1;
   for(; i<length; i++){
       ListNode *temp = (ListNode*)malloc(sizeof(ListNode));
       temp->m_nValue = data[i];
       temp->m_pNext = NULL;
       pNode->m_pNext = temp;
       pNode = temp;
   }
   return &pHead;
}

void FreeList(ListNode **pHead){
    ListNode *pNode;
    while(pHead!=NULL && *pHead!=NULL){
        pNode = *pHead;
        *pHead = pNode->m_pNext; // here will encounter an error;
        free(pNode);
    }
    pHead = NULL;
}

int main(){
    int data[] = {1,2,3,4,5};
    ListNode **pHead = CreateList(data, sizeof(data)/sizeof(int));
    FreeList(pHead);
}

But if I change the CreateList's return type to ListNode* CreateList(...), this will work well.

ListNode* CreateList(int data[], int length){
     if(length<=0 || data == NULL)
          return NULL;
   ListNode *pHead = (ListNode*)malloc(sizeof(ListNode));
   ListNode *pNode = pHead;
   pNode->m_pNext = NULL;
   pNode->m_nValue = data[0];
   int i=1;
   for(; i<length; i++){
       ListNode *temp = (ListNode*)malloc(sizeof(ListNode));
       temp->m_nValue = data[i];
       temp->m_pNext = NULL;
       pNode->m_pNext = temp;
       pNode = temp;
   }
   return pHead;
}
int main(){
    int data[] = {1,2,3,4,5};
    ListNode *pHead = CreateList(data, sizeof(data)/sizeof(int));
    FreeList(&pHead);
}
有帮助吗?

解决方案

In ListNode** CreateList(int data[], int length) approach you are returning pointer to a local variable, which clearly goes invalid when the function returns.

That is, you declare a pointer variable ListNode* pHead in CreateList function and you return address of the variable pHead. The pointer variable pHead is stored in stack and when the CreateList function returns the stack is unwinded memory used to stored pHead is freed eventhough the memory pointed to by pHead is still availalbe on heap.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top