I have this somewhat unconventionally coded linked list and am trying to remove the head of it.
This is a hashtable, so it's an array of linked list
myStruct *pointer = HashTable[i];
1->2->3->NULL
How can I delete the 1 and make 2 the head of the list?
I've tried pointer = pointer->next but when I re-display the table, it still is printing 1->2->3->NULL, not 2->3->NULL.
I would recommend the image I made for you. I think it is safer than saying something like :
node *temp = head
head =head->next
delete temp
Because depending on how you handle your pointers, you could run the risk of deleting your whole list. Doing it this way, you will lose the head and make sure you have the rest of the list. But do what you like! man - try things out.
void changethehead(node*&head) {
node *tobedeleted = head;
head = head->next; // head is the next element
delete tobedeleted; // delete the old head
}
Related
In function given below, I simply delete the head-pointer of the list and set head pointer to nullptr (im setting it nullptr because in my print function,I check for nullptr for head node, and ask user to create list first if head-node is nullptr).
void del_list(stud* &orig_head)
{
cout << "Deleting entire list..." << endl;
delete orig_head;
orig_head = nullptr;
}
I have a question regarding the way I choose to delete the list, since im not clearing each node of list, im simply clear the head pointer, what will happen to all the other nodes? Will this approach create a memory leak ?
Edit:
Im not using OOP to implement linked list,im implementing linked list using struct and couple of functions.
I like to handle this problem recursively:
void deleteNode(Node * head)
{
if(head->pNext != NULL)
{
deleteNode(head->pNext)
}
delete head;
}
If we have a list of 5 items:
head->pNext->pNext->pNext->pNext->NULL;
Then, the function will first get called for head, then for each pNext until the last one. When we reach the last one, it will skip deleting the next one (since it's null) and just delete the last pNext. Then return and delete the list from back to front.
This is assuming that each node's pNext is initialized to NULL. Otherwise, you'll never know when you've reached the end of the linked list.
Your code will cause memory leak. To delete it correctly, traverse the list and while traversing delete each node separately. And finally make head pointer to point to NULL value. You can have a look at the following code.
void deleteList(struct Node** head_ref)
{
struct Node* current = *head_ref;
struct Node* next;
while (current != NULL)
{
next = current->next;
free(current);
current = next;
}
//Now make head_ref point to null
*head_ref = NULL;
}
I am trying to implement a stack using a Linked List. My program keeps crashing and when trying to print the new Linked List, it prints an unsigned integer. My print function works fine, so it is this function below.
Please help.
void LinkedList::Push (int val)
{
Node* newHead = new Node;
Node* oldHead = new Node;
newHead->value = val;
oldHead = head;
head = newHead;
oldHead->prev = head;
head->next = oldHead;
delete newHead;
}
One issue is that the Node that you've newed in the definition of oldHead is never deleted. Since you set oldHead to head immediately after creating it, I would suggest this as your definition:
Node* oldHead = head;
The main issue, though, is that you delete newHead, which is now what head points to. Therefore, when you go to print head, you are reading invalid data.
I would highly recommend leaving the resource handling to objects like std::shared_ptr instead of newing and deleteing yourself.
I'm not sure I understood your question.
Your fixed method:
void Push( const int val )
{
Node* newNode { new Node };
newNode->value = val;
newNode->next = head;
head = newNode;
}
Read more about Linked List operations here. You do not need a doubly linked list to implement a stack - you only need to push/pop at one end.
[EDIT]
I didn't notice you are using a doubly linked list (this is why a complete/verifiable example is required). As I said, for a stack implementation, a singly linked list is enough.
NODE* InsertAtHead(NODE* &head, int val){
NODE *tmp = new NODE;
//create a new node
if (tmp == NULL)
exit(1);
//Initialize the new node
tmp->data = val;
tmp->next = NULL;
//Insert by changing links
tmp->next = head;
head = tmp; //update head
return head;
}
Why in the end we need to put return head?
The linked list you have is a singularly linked list. It only has references for next so you can only iterate to the end. If you have a pointer to the beginning you can get to everything, but if you have a pointer to the middle, you have no knowledge of the beginning.
In this function you are prepending, which creates a new beginning. If you don't return the new beginning then the calling function will have no knowledge of this element.
This is of critical impotance as you are using new to allocate memory and if it is not freed there will be a memory leak. It can't be freed unless the calling function has this pointer.
Linked list (when people say linked list they usually mean single linked list) has a link to the next node and no link to the previous one. So imagine if you return a node that is in the middle of list, you could get to next one and next one all the way to the end, this is good. Where you have a problem is that you will not be able to go to the previous node unless you have link to it, which would make it double linked list, or have pointer to the head first node in list which will serve as a start.
In your case you are pushing nodes onto the front of the list thus your code is pushing previous head to next and making new node a head node.
EDIT:
The head should be pass by reference. val should be passed by value. Why? For head we need an address of it so we could make a link to it. For val if we would pass it by reference, the address might be reused in caller function and we do not want our data to change.
I am implementing a stack using a singly linked list where the Head is at the top of the stack and the Tail is at the bottom of the stack.
I am implementing a pop operation. In order to do this, I must make the head equal to the second node in the linked list. But before I do this, I need to delete the first node in the linked list first. I can do this using delete head->next;.
My question is, if I delete that first node, can I still use it to move on to the next node? Or is it bad practice to use a reference of a node that has had delete called on it. Here is the code I want to use to implement pop.
delete head->next;
head->next = head->next->next;
If you do:
delete head->next;
Then head->next is invalid. If you try to dereference it in the next line (remember the right hand side will be evaluated before the assignment), your program will crash.
head->next = head->next->!next; // dereference of the bad pointer happens where I put the !, and you crash there.
If you want to delete the object at head->next you will need to save it off first.
p = head->next;
head->next = head->next->next;
delete p;
First, once something is deleted, it is gone. Don't access deleted memory.
Second, why are you saying head->next = head->next->next? Shouldn't head = head->next be good enough for pop? In a empty list, head would be nullptr, wouldn't it?
Third, why are you not using std::list?
Last, order of operation is sometimes important, especially when the linked list might be shared by multiple threads. This is how I'd implement pop (and optionally make it multithread safe):
void list::pop() {
// optionally, acquire mutex
node* to_be_deleted = head;
head = head->next;
if (head == nullptr) tail = nullptr;
// release optional mutex here
delete to_be_deleted;
}
There's 2 pieces of code that I can't seem to find the bug with. I know there is something wrong within these. One for each.
int pop()
{
Node* temp = new Node();
temp = tail;
tail->prev()->setNext(NULL);
int tempV = temp->key();
delete temp;
return tempV;
}
The other piece of code is this:
int main()
{
Node* t = new Node(0,NULL);
t = Node(1,t);
t = Node(2,t);
delete t;
}
I thought about the 2 pieces of code for a while. For the 1st piece of code, I think the error is that you shouldn't create the Node* temp on the heap with the keyword new. It should just be Node* temp = tail; I believe. Can anyone confirm that?
For the 2nd piece of code, I thought the error was that you don't need both
t = Node(1,t);
t = Node(2,t);
EDIT::I'm sorry I made a mistake. It was supposed to be Node rather than node. My friend told me it has to do something with memory. It there a memory leak because of the multiple nodes being declared with new? Or do we need the new keyword for the last 2?
Thanks
When you pop the element, you need not create a "new" node. You have to remove the last element of the linked list - not create a new node.
For your second question, you do not need the
t = node(1,t)
t = node(2,t)
if the function returns the currently added node.
But if the function returns the header of the linked list, it is required. It depends on how you write the node function.
you are losing the value you new
Node* temp = new Node();
temp = tail; <-- you just lost the value you new'ed
then later you are deleting a different node
tail->prev()->setNext(NULL); <-- this line doesn't check that the value for prev() isn't null
as to what is going on in main I would need to see more of the code for "node"
Dinesh is correct in the first example. Here is a little more explanation.
Node* temp = new Node()
temp = tail;
results in a memory leak. the new node that was created is leaked when you overwrite temp to tail. The proper way to do it would be
Node * temp = tail;
In the second example its not clear what the node function does. If you meant to write this:
int main()
{
Node* t = new Node(0,NULL);
t = new Node(1,t);
t = new Node(2,t);
delete t;
}
The code would make more sense, it creates a linked list of three nodes containing 2, 1, 0 when listed from head to tail. It's hard to tell from the incomplete example.
In pop you have a memory leak. You construct a Node on the heap and then immediately lose track of it, like inflating a balloon and letting it go:
Node* temp = new Node();
temp = tail;
But you also have a more serious problem: you do not adjust tail. When the function is finished, tail points to a region of memory where the last node used to be, and any attempt to dereference it will cause Undefined Behavior.
As for your second question, the code might be correct, and it might not. There's no way to tell unless/until you show us what node(...) does.