Reputation: 7649
I'm writing a hashtable as an array of linked lists.Currently I'm trying to have a simple hash table where the key is the index of the array and value is a singly linked list for implementing chaining.
This is my code to delete a node:
Basic Struct:
struct Node
{
int value;
int page;
struct Node *next;
};
int searchAndDelete(int frame,int page,int delete)
{
struct Node** iter;
iter=&hashtable[(page-1)%7];
struct Node** prev=iter;
for(;*iter;iter=&(*iter)->next)
{
if(page==((*iter)->page))
{
if(frame==((*iter)->value))
{
if(delete)
{
(*prev)->next=(*iter)->next;
free(*iter);
}
return 1;
}
}
prev=iter;
}
return 0;
}
For insertion please take a look here, AddNode
When I'm deleting a node, the value for that changes to 0. When I search for the node it gives back that node is not preset aka 0 as output from the function.
Are there any mistakes in my code which I haven't thought about?Am I leaving any memory leaks or any other problems?
Edit Added this piece of code to the delete function:
int searchAndDelete(int frame,int page,int delete)
{
struct Node** iter;
iter=&hashtable[(page-1)%7];
struct Node** prev=iter;
struct Node** curr=iter;
for(;*curr;curr=&(*curr)->next)
{
if(page==((*curr)->page))
{
if(frame==((*curr)->value))
{
if(delete)
{
if(curr==iter)
{
iter=(*curr)->next;
free(*curr);
}
else
{
(*prev)->next=(*curr)->next;
free(*curr);
}
}
return 1;
}
}
prev=curr;
}
return 0;
}
Problem I'm seeing is that when I delete the first time, the element is not freed, it's value is set to 0, but it still says in the linked list. In the second deletion the value of the last elements goes to some garbage and hence that element will never be deleted in my comparison checks. Can someone shed light on what I might be doing here?
Upvotes: 1
Views: 2138
Reputation: 66224
If the hash table you're using is seven elements wide (i.e. 0..6 for indexes), and from your AddNode code, it appears it is, then the arithmetic you're using is suspect for the initial iterator find.
iter=&hashtable[page-1%7];
should likely be:
struct Node** iter = hashtable + (page % 7);
This will give you the address of the element in your hash table at the page location modulus 7, i.e. [0..6].
Also, your delete from your hash table head node doesn't account for clearing the table element itself. You may need to (a) set it to null, or (b) chain in the next ptr. Do that as well. You have the ability to since the hash table and the initial node pointer are both available.
EDIT: OP asked for sample. This is just a quick jot of how this can be done. I'm sure there are plenty of better ways, maybe even ones that compile. This assumes both the page AND frame must match EXACTLY for a node to be considered delete'able.
void searchAndDelete(int frame, int page, int del)
{
struct Node** head = hashtable + (page % hashtable_size);
struct Node* curr = *head;
struct Node* prev = NULL;
while (curr)
{
// if they match, setup for delete.
if ((curr->page == page) && (curr->value == frame) && del)
{
// so long as the header pointer is the active node prev
// will be NULL. move head along if this is the case
if (prev == NULL)
*head = curr->next;
// otherwise, the previous pointer needs it next set to
// reference the next of our vicitm node (curr)
else
prev->next = curr->next;
// victim is safe to delete now.
free(curr);
// set to the new head node if we just deleted the
// old one, otherwise the one following prev.
curr = (prev == NULL) ? *head : prev->next;
}
else
{ // no match. remember prev from here on out.
prev = curr;
curr = curr->next;
}
}
}
Eh, close enough =P
Upvotes: 2
Reputation: 53336
I see couple of issues:
mod operator %
needs parenthesis. So change iter=&hashtable[page-1%7];
to iter=&hashtable[(page-1)%7];
Handle the case when you will delete 1st element in linked list. In such cases prev
will be same as iter
so (*prev)->next=(*iter)->next;
will not make any different. You need to update the array to store next element aka (*iter)->next
.
Upvotes: 1