Question

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);
}
Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top