问题
Hey everyone I am getting a memory leak in my remove head function. I think it could be that im not freeing the head but I can't seem to find the correct place to put it. I was thinking right above the line that says L->head = L->head->next;
data_t * removehead(list_t *L) {
data_t *temp = NULL;
}
if (L->head != NULL) {
temp = L->head->data_ptr;
L->head = L->head->next;
L->size--;
}
return temp;
}
Any thoughts?
回答1:
It's a matter of taste, if you don't want to declare a specific variable then you are forced to do it before L->head = .. or you won't have any reference to old head anymore.
But you can always have a more readable way:
element *old_head = L->head;
temp = L->head->data_ptr;
L->head = L->head->next;
--L->size;
free(old_head);
The only thing I'm wondering about is what happens to pointed data_t* of old head? Because it will leak too if you don't have any reference to it around.
回答2:
You could have two functions, one that shows the current list head, and another that drops/pops the current list head,
data_t*
listHead(list_t* lp)
{
if(!lp) return lp;
if(!lp->head) return NULL;
data_t* dp = lp->head->data;
return dp;
}
data_t*
listPop(list_t* lp)
{
if(!lp) return NULL;
data_t* dp = NULL;
if(lp->head)
{
if(lp->head == lp->tail) lp->tail = NULL;
node_t* head = lp->head;
lp->head = lp->head->next;
dp = head->data;
nodeDel(head);
lp->size--;
}
return dp;
}
And a complete (singly) linked list ;-),
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef void data_t;
data_t*
dataNew(data_t* dp,int size)
{
if(!dp) return NULL;
data_t* data = (data_t*)malloc(size);
if(!data) return data;
memcpy(data,dp,size);
return(data);
}
void
dataDel(data_t* dp)
{
if(!dp) return;
free(dp);
return;
}
typedef struct
{
void* next;
data_t* data;
} node_t;
node_t*
nodeNew(data_t* data)
{
node_t* np = (node_t*)malloc(sizeof(node_t));
if(!np) return np;
np->next=NULL;
np->data = data;
return(np);
}
data_t*
nodeDel(node_t* np)
{
if(!np) return np;
data_t* data = np->data;
free(np);
return(data);
}
typedef struct
{
int size;
node_t* head;
node_t* tail;
} list_t;
list_t*
listNew()
{
list_t* lp = (list_t*)malloc(sizeof(list_t));
if(!lp) return lp;
lp->head = lp->tail = NULL;
lp->size=0;
return(lp);
}
int
listEmpty(list_t* lp)
{
int count=0;
if(!lp) return 0;
while (lp->head)
{
node_t* np;
data_t* data;
count++;
np = lp->head;
lp->head = lp->head->next;
data = np->data;
free(np);
free(data);
}
return count;
}
int
listDel(list_t* lp)
{
if(!lp) return 0;
int count=listEmpty(lp);
free(lp);
return count;
}
int
listCount(list_t* lp)
{
if(!lp) return 0;
return(lp->size);
}
data_t*
listHead(list_t* lp)
{
if(!lp) return lp;
if(!lp->head) return NULL;
data_t* dp = lp->head->data;
return dp;
}
data_t*
listTail(list_t* lp)
{
if(!lp) return lp;
if(!lp->tail) return NULL;
data_t* dp = lp->tail->data;
return dp;
}
node_t*
listPush(list_t* lp, data_t* data)
{
if(!lp) return NULL;
if(!data) return NULL;
node_t* np = nodeNew(data);
if(!np) return np;
if(lp->tail)
{
lp->tail = lp->tail->next = np;
}
if(!lp->head)
{
lp->head = lp->tail = np;
}
lp->size++;
return np;
}
data_t*
listPop(list_t* lp)
{
if(!lp) return NULL;
data_t* dp = NULL;
if(lp->head)
{
if(lp->head == lp->tail) lp->tail = NULL;
node_t* head = lp->head;
lp->head = lp->head->next;
dp = head->data;
nodeDel(head);
lp->size--;
}
return dp;
}
int
main()
{
list_t* lp;
data_t* data;
int ndx;
if( !(lp = listNew()) )
{
printf("error: cannot allocate list\n"); exit(1);
}
for( ndx=0; ndx<100; ++ndx )
{
data = (data_t*)malloc(100);
sprintf(data,"node:%d",ndx);
if( !listPush(lp,data) )
{
printf("error: cannot push %s\n",data);
free(data);
}
}
while( listCount(lp) > 0 )
{
data = listPop(lp);
printf("data: %s\n",data);
free(data);
}
}
来源:https://stackoverflow.com/questions/19148576/memory-leak-in-removehead-function