I have created a class which includes a linked list and this class needs to have a destructor for deleting the linked list, which I have included however because the delete method itself calls the destructor I end up in an infinite recursive call situaction.
Here is the code:-
PolynomialNode::~PolynomialNode()
{
/*PolynomialNode* current_node_ptr = link;
PolynomialNode* header_ptr = link;
int index = 0;
if( link != NULL)
{
while( current_node_ptr != NULL)
{
index++;
current_node_ptr = current_node_ptr->get_link();
}
delete_nodes( &header_ptr, 0, index);
} */
PolynomialNode* current_node_ptr = link;
PolynomialNode* copy_ptr;
while( current_node_ptr != NULL)
{
copy_ptr = current_node_ptr->get_link();
current_node_ptr->set_link(NULL);
delete current_node_ptr;
current_node_ptr = copy_ptr;
}
}
Note I tried this with a recursive call - intentional for deleting the linked list and I still have the same problem.
Any help would be much appreciated.
NB: I know it's a recursive call because when I step through the debugger I can see it happening.
assuming link is the pointer to the next PolynomialNode, simply
PolynomialNode::~PolynomialNode()
{
delete link;
}
will do the right thing recursively.
However, a better solution might be to retain your while() loop but move it out of the node to the destructor of a separate class representing the linked list as a whole.
Add this line in the while loop, before delete:
if ( current_node_ptr == this ) continue;
This will allow you to avoid recursion, by skipping destruction of the node that is calling. However, you should ask yourself why the heck did this happen in the first place. I cannot answer that question, because I don't see the rest of the code.
Note: this is wrong unless you have a circular link, in case of which this would be a valid design, as long as you skip deleting this.
Assuming link is the pointer to the next PolynomialNode, simply
if(this->link != NULL) delete this->link;
Related
I need to work on a function that resets a linked list without completely eliminating it, and I wanted to know if my piece of code is right. Any other suggestions?
void reset(){
if (initial == nullptr){
return;
}
Node<T> *flag;
Node<T> *temp;
while(initial->obtainNext() != nullptr){
flag = initial->();
temp = flag->obtainNext();
delete flag;
inicial->setNext(temp);
}
initial->setNext(nullptr);
return;
}
By my understanding you're trying to erase your linked list.
1. You may just loop through the given node and delete all of them setting the head node as nullptr.
2. You may make an object which holds that linked list and may serve your purpose by using method 1 in erasing everybody but the object still exists with a variable set to nullptr.
I suppose you have already implemented pop_back() \ pop_front() \ erase() method in your class so it is possible to not write some new additional logic but use existing one with any loop as followed:
void clear
{
while(this->size) //can be class field which indicates list's size or call size() method
this->pop_front();// can be changed as mentioned above
}
void intersectionLists(LinkedList argList) {
bool common = false;
ListNode* thisCurrentPointer{headPointer};
ListNode* argCurrentPointer;
cout <<"common elements between both lists are:\n";
while(thisCurrentPointer != nullptr) {
argCurrentPointer = argList.getHeadReference();
while(argCurrentPointer != nullptr){
if(thisCurrentPointer->data == argCurrentPointer->data) {
cout <<thisCurrentPointer->data;
common = true;
break;
}
argCurrentPointer = argCurrentPointer->nextPointer;
}
thisCurrentPointer = thisCurrentPointer->nextPointer;
}
if(!common) {
cout <<"none\n";
}
thisCurrentPointer = nullptr;
argCurrentPointer = nullptr;
delete thisCurrentPointer;
delete argCurrentPointer;
}
Hello everyone,
Iwas making this function for intersection in the linkedList class, which has the parameter of another linkedList object, one utility function i am using on line 9 is getHeadReference(), which simply returns the address stored in the headPointer (i am using this function in order to get argCurrentPointer to point at the head of the list that came in the parameter).
Anyway.. the function gives perfectly fine output of whatever two linked lists are but the control get "stuck" right after its execution, the control freezes, and a huge garbage value is returned, i really hope i am being clear.
I have dry run the code i can not seem to find the problem. Even in main when i call another function after the execution of "intersectionLists" function, the called function gets executed properly without any delay but the control can't seem to exit main after all the work is done, when i don't call this intersection code, no hang or delay whatsoever is observed, please help. Thank you.
I think this is because you detele thisCurrentPointer and argCurrentPointer after setting them to null. It is not necessary to do any deletion after as you are not duplicating your nodes.
So I'm working on making a linked list, and everything about it is working exactly as I want it to except for the list's destructor:
PhoneList::~PhoneList()
{
PhoneNode *ptr = head;
while (ptr != NULL)
{
head = head->getNext();
delete ptr;
ptr = head;
}
}
When the program runs, it does everything else I need it to, but then seems to loop indefinitely on the destructor when it tries to call it and end the program. This is my first question here, and I'm a bit of a newcomer to this whole programming thing, so if you need to see any more of my program code to make sense of this destructor I will gladly share it!
You would be better off adding a destructor for PhoneNode, such that each each deletes its successor. Then you don't need the loop at all:
PhoneNode::~PhoneNode()
{
delete next;
}
Note that this traverses the entire remaining list.
then your PhoneList destructor just looks like:
PhoneList::~PhoneList()
{
delete head;
}
Take care in your Delete(int id) method that you zero the next pointer of a node you're going to delete if it's in the middle of the list (i.e. it isn't already zero). Otherwise you lose the entire rest of the list.
This is a school assignment and I have most of it under control, but there is a small part that is creating a memory leak and I have no more ideas on how to fix it.
We have created a memory allocator, and the trouble part are this two functions.
This first one cannot be modified
void destroy (){
free():
tot_alloc = 0; }
This second one is the one I'm working on
void free(){
munmap(pool, PAGE_SIZE);
Page* f = this;
f = f->prev;
if (f != NULL)
f->destroy();
}
I have written all of the free() function and was asked in the assignment to call destroy().
I realize that this function is not destroying the first "this" because immediately is going to f->prev but I have no clue how to make it first destroy this and the go to prev.
I hope this is not a too silly question.
Many thanks!
Nico
To remove an element from a singly-linked list, you must walk to that element to find the element before it in the list. Then you have to 'stitch' around it. Like this:
void free()
{ // Note: This has no error checking!
Page *f = tail, *next_f = NULL;
while(f != this)
{ // find this node to find the node after this node
next_f = f;
f = f->prev;
}
// found it. Now, next_f is the node after this node.
// close the chain so this link can go away
if (next_f == NULL) // there is no node after us, we must be the tail
tail = prev; // the tail is now whatever node is after us
else // in the node after us, the node before it is now the node before us
next_f->prev = prev;
destroy(); // we are unlinked from the chain so can now be freed
}
The nature of pointers being NULL in C++ seems to feel arbitrary. I'm sure there's a method to it that I'm missing, but the following makes sense to me, but doesn't seem to work. I have the following method for adding a node to a linked list:
LLNode *ll; // set to NULL in constructor.
void addToLL(Elem *e)
{
LLNode *current = ll;
while(true)
{
// edge case of an empty list.
if (ll == NULL)
{
ll = new LLNode(e);
break;
}
else if (current == NULL)
{
current = new LLNode(e);
break;
}
else {
current = current->next;
}
}
}
When adding a 2nd node to the list, the case for current == NULL does not get caught, so it tries to call current = current->next and crashes do to accessing invalid memory. Why would this be the case? A LLNode has a pointer to an Elem, and a pointer called next to another LLNode.
You probably didn't set the next pointer to NULL in the LLNode constructor.
Objects of the basic types in C++ (pointer types, numeric types, etc.) have indeterminate initial values: they don't get initialized by default. You need to explicitly initialize such objects before you use them.
For this sort of thing you need a pointer to a pointer in order to strip away a lot of the needless exceptions in your implementation:
LLNode *ll = NULL;
void addToLL(Elem *e)
{
LLNode** current = ≪
// While the current pointer to pointer is mapped to something,
// step through the linked list.
while (*current)
current = &(*current->next);
// At this point current is pointing to a NULL pointer and can
// be assigned to.
*current = new LLNode(e);
}
The reason pointers are NULL is because that evaluates to false and allows you to do simple checks such as while (*current) without a lot of overhead. In the CPU this usually ends up being implemented as a test-if-zero operation.
Pointers are only NULL if initialized as such. In C they are often undefined unless properly initialized and referencing an uninitialized pointer is recipe for disaster. You'll want to ensure any pointers you define are always initialized to something valid before using them.
1) You say that ll is set to NULL in the constructor. But what constructor? There's no class definition here. Is ll a global variable? And are you sure that the constructor for LLNode sets the next pointer to NULL?
2) The condition
if (ll == NULL)
can and should be checked outside of the loop, as ll is not modified inside the loop.
3) current is a local stack variable, so assigning to it will have no effect once the function exits. In particular, current = new LLNode(e) is a memory leak.
4) To add a node to the linked list, you must find the last node of the existing list, and modify its next pointer. Something like this would work:
// ll is a field representing the first node in your existing linked list.
if (ll == NULL) {
ll = new LLNode(e);
}
else {
current = ll;
while (current->next != NULL) {
current = current->next;
}
current->next = new LLNode(e);
}
EDIT: Modified the above based on your comment that ll is a class member.
The first thing I see in your code is that current is local, gets allocated with new but is never actually attached to the list.
Surely your code should be
else if( current->next == NULL )
{
current->next = new LLNode( e );
break;
}
LLNode must of course initialise next to NULL in its constructor.
Of course your list has O(N) insertion time, and if this is anything other than an exercise you should be almost certainly be using standard library containers.
You should also probably move the edge case out of the loop.