I have created a function to append a node at the front of a linked list in c++. If I don't comment the last line i.e. the delete temp line, the program runs into an infinite loop but if I comment it, everything runs fine. I was hoping to free the memory allocated to the pointer temp to avoid memory leak. Why is it causing a problem?
void addFront(Node **head, int item)
{
Node *temp = new Node(); // Allocating new memory.
temp->data = item; //Storing data in the node.
temp->next = *head; //Linking temp pointer to head pointer.
*head = temp; //Resetting the head pointer as the new first node.
//delete temp; //Deallocating memory.
}
You are calling 'new' once, so you only allocated node once. There is no need to "avoid leak" since you never copied the node.
Don't confuse pointers with the pointee. delete temp deletes the object pointed to by temp, but that is the node you just inserted in your tree.
You do not need to manually manage the memory of the pointer itself, because it uses automatic storage.
new Node(); does more than allocating memory. It allocates memory and creates a Node by calling its constructor. Instead of two phase construction, members should be initiliazed by calling the constructor.
Slightly modified comments:
void addFront(Node **head, int item)
{
Node *temp = new Node(item,*head); // create new node. temp is a pointer to it
*head = temp; // head points to the new node
//delete temp; // delete the new node ?!?
}
There is no memory leak, because now *head does point to the newly created node.
This is a memory leak:
void foo() {
int* x = new int;
}
because after the function returns you have no way to access x and have no way to release its memory. While this is not a memory leak:
void bar() {
int * x;
}
As mentioned above, x itself uses automatic storage and its memory is released automatically when the function returns. Colloquially we say: x is allocated on the stack.
Why is it causing a problem?
If the purpose of the function is to add a new node, then it should follow that there would be more nodes after the function than there were before calling the function.
If you create one node, and delete it, then there would be no more nodes after the function than there was before. This contradicts with the described postcodition that there should be more nodes than there was before.
You haven't shown the part of the program where you do this, but presumably you somehow use the list after you've created it. You cannot use nodes that you've already deleted.
If I don't comment the last line i.e. the delete temp line, the program runs into an infinite loop
Deleting the node there is the wrong way to fix the infinite loop that you haven't shown.
I was hoping to free the memory allocated to the pointer temp to avoid memory leak.
You will have to follow the following order of operations:
Create node
Use node
Free node
You cannot do the following. It won't work:
Create node
Free node
Use node (can't do this after freeing the memory)
Related
So I was learning how to make a linked list, and I was wondering why we need to use "new" when adding a node. Below is function that adds a node correctly:
void addNode(int value){
Node* new_node_ptr = new Node;
new_node_ptr->value = value;
if (root == NULL){
root = new_node_ptr;
traveler = new_node_ptr;
} else {
traveler->next = new_node_ptr;
traveler = new_node_ptr;
}
}
But, since I am new to c++, when I tried to figure out how to do this by myself, instead of having the line:
Node* new_node_ptr = new Node;
I wrote:
Node new_node;
Node* new_node_ptr = &new_node;
This doesn't work. It seems that the new_node variable keeps being assigned to the same memory address each time you try to add a new node. This is simultaneously fascinating and infuriating. Could anybody explain this c++ weirdness to me?
Thanks!
When you write
Node new_node;
The variable is created on the stack and should not be used once addNode exits. addNode loses "ownership" of that memory once the function exits, and memory associated with new_node is allowed to be used again by other parts of your program. Attempting to use it is undefined behavior and cannot be relied upon.
You must allocate memory dynamically to ensure that the life of the data extends beyond the scope of the function.
In the second case with stack allocation, if new_node is always assigned memory at the same address, that's just how it happens to work out in your test case. Depending on the order of other functions being called before addNode, that may not always happen, and likely won't consistently in a "real program".
When you declare a variable without using new, you are saving a portion of memory allocated in the stack. Variables stored in the stack belong inside a function but not outside (for example, a counter, iterators, etc.).
When you declare by using new, you save a portion of memory allocated in the heap. Variables stored in the heap can be accessed in your entire program (and, by some methods, by other programs too).
You can find more detailed information in the following link:
https://www.gribblelab.org/CBootCamp/7_Memory_Stack_vs_Heap.html
Node* new_node_ptr = new Node;
The above means "create a new node object and keep it indefinitely long".
Node new_node;
Node* new_node_ptr = &new_node;
The above does not mean "create a new node object and keep it indefinitely long".
If both versions did what you want them to do, now that would be weird, because then ithe new construct would appear to serve no legitimate purpose whatsoever.
I implement the following code to delete element at Head. When program runes to "delete p", it will impact the previous Head and Head gets to NULL. What happened?
Node<T>* p;
p = Head;
Head = Head->next;
delete p;
This function will delete the 1st node (node
pointed to by head). It returns true if the node was deleted else false if the list is empty.
Using double pointers for the input parameter (head) here because head will
have to be updated and this value should reflect
outside this function.
bool deleteHeadElement(Node** head)
{
if (*head == nullptr)
{
// List is empty, nothing to delete
return false;
}
// Store the node that has to be deleted
Node* nodeToDelete = *head;
// Update the head to point to next nodeToDelete
*head = nodeToDelete->next;
delete nodeToDelete;
// 1st element of node has been deleted.
return true;
}
After the call to this function, you may subsequently call it and it will take care of the scenario in which the list becomes empty after the previous calls.
NOTE:
Regarding the value 0xfeeefeee, it seems you are trying to somehow freeing already freed memory. Perhaps you should check if your head is properly getting updated.
Also, make sure that you are freeing memory of the node by using delete only if it was allocated using new. delete takes care if the memory to pointed is NULL.
If you had allocated memory to the node using malloc(), you should be deallocating using free().
I'm trying to improve my C++, so I decided to start fresh and went through a few tutorials.
It seems to be a general rule that each "new" operation has to be followed by "delete" eventually, to avoid risking a memory leak.
Then, I stumbled across the following code segment on a tutorial regarding linked lists:
struct node {
int data;
node* next;
};
class linkedlist {
private:
node* head;
node* tail;
public:
linkedlist(){
head = null;
tail = null;
}
void delete_first()
{
node *temp=new node;
temp=head;
head=head->next;
delete temp;
}
// additional functions for add/delete/display, ...
}
The problem I'm having here, is understanding the delete_first() function completely.
Create a new node in dynamic memory and assign it to 'temp'
Set temp's pointer to now point at the head instead (but what happened to the new node?)
Make the head's subsequent element the new head
Delete temp from memory
I assume that the tutorial would not introduce memory leaks, but it certainly seems to me as if each call of delete_first() would generate an extra struct that's never deleted.
Okay, there's both a 'new' and a 'delete', but wouldn't that suggest that the amount of elements in memory stays the same?
Could anybody please clear me up and elaborate why there's no(?) memory leak happening in this case?
You are correct.
That’s a bug in the tutorial you were reading. It shouldn’t be creating a new node in delete_first(). Instead, it should be setting temp to head when it’s declared.
I have a doubt which is as follows...
Linked List deals with pointers and dynamic allocation. So they have provided a keyword new which allocates a chunk(that's how it's spelled I suppose) of memory in the heap store and returns a pointer pointing to it. And they have also provided the delete keyword which frees the memory to which the pointer returned by the new is pointing.
So suppose I've created a Linked List of say 10 nodes then should I have to create a function to scan through each node and delete each node? Because in my textbook they have written that if you don't delete a dynamically allocated object then it causes memory leak...
So in short do I have to scan through each node deleting each node before closing a C++ console application??
Aditional Details
Operating System Windows 7
Compiler Turbo C++
It is a good practice that for each memory allocated, there is a class or function responsible for freeing it if it won't be used any more.
Still, all the memory used by program will be freed by operating system when the program is closed. But I think that your teacher (homework, isn't it?) or boss would rather you freed the memory.
The bottom line is: delete everything you created with new.
So in short do I have to scan through each node deleting each node
before closing a C++ console application??
Sure you can delete it before closing your problem, if you did not delete it, then operating system will anyway clear memory consumed by your application / program.
Once, if you know, your heap memory is no more useful better to delete it (instead of waiting for closing program)
{
Allocation with new...
call function(using allocated memory)
....
....
call function2(using allocated memory)
not using allocated memory here after..
**Delete Your heap memory..**
call AnotherFunction()
....
...
Alternatively, you can release / delete memory here also. (Good practice than not deleting :) )
end of main / application.
}
No, you don't actually have to do so.
Nearly all code should, however, be written in a way that the data gets deleted when the object that owns it goes out of scope, so this will happen (almost) unavoidably.
In other words, you should not normally have something like:
// WARNING: bad code. Avoid this, or anything similar.
struct node {
int data;
struct node *next;
};
node *head = NULL;
int main() {
node *t = new node;
t->data = 1;
t->next = head;
head = t;
t = new node;
t->data = 2;
t->next = head;
head = t;
// here, do we bother to delete the two nodes or not?
};
Instead, what you normally want to do is create a class that encapsulates all the work, and in its destructor it frees all the memory it owns:
class linked_list {
struct node {
int data;
node *next;
node(int data, node *next = NULL) : data(data), next(next) {}
} *root;
public:
void add(int data) {
root = new node(data, root);
}
~linked_list() {
node *prev = root;
for (node *temp = prev->next; temp!=NULL; temp=temp->next) {
delete prev;
prev = temp;
}
delete prev;
}
};
With a class like this, there's really no decision to make:
int main() {
linked_list x;
x.add(1);
x.add(2);
}
When execution reaches the end of the block in which x was defined, x goes out of scope and gets destroyed. In the process, its destructor is invoked, and that deletes the nodes in the linked list (modulo any bugs in my code, of course). There's no need to think or care about whether it makes sense to delete the nodes in this case, because it simply happens automatically every time.
Note that I'm not saying this code is (even close to) 100% ideal either. With a compiler modern enough to support it you'd almost certainly want it to be a template to allow storing an arbitrary type, and use a unique_ptr and make_unique instead of a raw pointer and raw new. Unfortunately, I have little choice but to leave these out, since I'm sure Turbo C++ doesn't support unique_ptr, and doubt it supports templates either. For real use, this should also include a copy constructor and assignment operator as well, so assigning and copying linked lists would work correctly (as it stands now, either will typically lead to problems because it'll end up attempting to destroy the nodes in the linked list twice).
Final note: of course, you usually shouldn't write your own linked list code anyway. But when/if you do have a reason to writer a container (or something similar) it should clean up its own mess, so to speak. One of the real strengths of C++ is deterministic destruction; use it.
I am having a problem with delete and destructor (I am sure I am making a stupid mistake here, but haven't been able to figure it out as of yet).
When I step through into the destructor, and attempt to call delete on a pointer, the message shows up "Cannot access memory at address some address."
The relevant code is:
/*
* Removes the front item of the linked list and returns the value stored
* in that node.
*
* TODO - Throws an exception if the list is empty
*/
std::string LinkedList::RemoveFront()
{
LinkedListNode *n = pHead->GetNext(); // the node we are removing
std::string rtnData = n->GetData(); // the data to return
// un-hook the node from the linked list
pHead->SetNext(n->GetNext());
n->GetNext()->SetPrev(pHead);
// delete the node
delete n;
n=0;
size--;
return rtnData;
}
and
/*
* Destructor for a linked node.
*
* Deletes all the dynamically allocated memory, and sets those pointers to 0.
*/
LinkedListNode::~LinkedListNode()
{
delete pNext; // This is where the error pops up
delete pPrev;
pNext=0;
pPrev=0;
}
It seems that you are deleting the next and previous nodes of the list from the destructor. Which, if pNext and pPrev are LinkedListNode*, means that you are recursively deleting the whole list :-(
Try this:
std::string LinkedList::RemoveFront()
{
LinkedListNode *n = pHead->GetNext(); // the node we are removing
std::string rtnData = n->GetData(); // the data to return
// un-hook the node from the linked list
pHead->SetNext(n->GetNext());
n->GetNext()->SetPrev(pHead);
n->SetNext(0);
n->SetPrev(0);
// delete the node
delete n;
n=0;
size--;
return rtnData;
}
LinkedListNode::~LinkedListNode()
{
}
(Actually you don't even need to reset the prev and next pointers to 0 since you are going to delete the node anyway. I left those statements in because they at least put the node into a consistent state, which is a good idea in general. It may make a difference if you later e.g. change your memory management strategy and decide to store unused nodes for later reuse.)
It seems that your LinkedListNode is deleting its neighbours, so when you delete one node it then proceeds to destroy the entire list - note you don't set pNext and pPrev to NULL when you remove your node.
Also your LinkedListNode destructor is problematic even in the case when you want the whole list to be destroyed: having both delete pNext and delete pPrev will lead to multiple calls of the same destructor (and I think eventually a stack overflow).
Actually you shouldn't be messing with neighbours in a node. That's for list class to do - connect them properly. In the destructor you can set them to null, but unless you have allocated dynamically something else - you don't have to call delete