Linked lists implementation issue - c++

I'm trying to make a Stack using an underlying linked list structure.
Maybe I'm wrong, but I'm having trouble with the remove() function.
int Stack::remove(){
node* victim = new node;
int popped;
popped = top->element;
victim = top;
top = victim->next;
delete victim;
return popped;
}
I'm getting glibc dectecting
double free or corruption (out);
Since I'm allocating new memory with victim, don't I have to delete victim, or is that something I don't have to worry about?

A stack is much like a bunch of dishes that are being washed and set on top of one another. That is the first one in is the last one out (FILO data type). That is if your stack read in 2, 7, 8 then it would appear as :
8
7
2
That is first the 2 is placed in the stack, followed by the 7 and then by the 8. If you want to remove or pop the stack you need to move the head of the pointer. Your code looks a bit strange to me...
int Stack::remove()
{
int datum; //to store the popped value
node* temp=head; //assign pointer to head of list
datum = temp->data; //grab the data value stored at the head (or temp since they carry same reference)
head = temp->next; //move the head pointer (in our example now it points to 7)
delete temp;
return datum;
}

There's no reason to allocate heap memory in a remove() method as you are doing with victim. What you want is:
int Stack::remove(){
node* new_top = top->next;
int popped = top->element;
delete top;
top = new_top;
return popped;
}

You don't need to allocate a node for victim. Just assign the top of the stack to it and, if it's not null, set top to its next pointer, retrieve the value from victim, and then deallocate the victim.
It's not actually a corruption, but a memory leak - you are allocating a node, and then override that pointer with victim = top; thus losing track of just allocated memory.

Related

C++ pointer not null but cannot be freed

I'm implementing an open HashTable. My trouble arises in the destructor, where I iterate through all the buckets in an array, for each array I would delete all the nodes in a linked list.
// Deallocate all buckets
for (int i=0; i<maxBuckets; i++) {
Cell * p = m_data[i];
while (p != nullptr) {
Cell * temp = p;
p = p->next;
delete temp;
}
}
delete [] m_data;
But it reports pointer being freed was not allocated on the delete operation. What is going wrong here?
The error is pretty clear. You tried to delete a value that was not returned by new.
What we don't know is if the value is the address of a non-allocated value, just uninitialized (garbage) or if you've corrupted the heap. You haven't provided information to determine that.
But you do know that the value you are trying to free is not correct, and you need to figure out where it came from.

Why do we have different effect when setting pointer=nullpointer and pointer->next=nullpointer in linked list - C++

I have the following code snippet (regarding singly linked list) -
class Node
{
public:
int data;
Node* next;
};
Node* newNode(int data)
{
Node* temp = new Node;
temp->data = data;
temp->next = nullptr;
return temp;
}
int main()
{
Node* head = newNode(2);
head->next = newNode(4);
Node* p1 = head;
p1 = nullptr;
return 0;
}
Here, head and p1 are separate variables - meaning separate memory location. So, when we do p1=nullptr, only p1 should be effected, and not head. And, this is what happens, when I debug the code (as seen in the image below):
But, when I do p1->next=nullptr instead of p1=nullptr, head is also effected. As shown in the image below:
p1 and head are different memory locations. Hence p1=nullptr does not effect head. But why does p1->next=nullptr effect head?
p1 points to a string of pointers and head also points to a string of pointers (p1->next->next->next... and head->next->next->next...). p1 is at the same memory location as head. And p1->next and head->next are also at the same memory location (after we say p1=head), and so are the other next pointers. So, why does setting p1 to nullpointer (or any other value) does not effect head. But, setting p1->next to nullptr, effect head? If you could answer me with a boxed diagram for how the memory is working here, it will be helpful. Thanks!
You are misinterpreting what you're seeing in your debugger. head is unaffected.
The only thing that head is, by itself, is the memory address. Nothing more, nothing else.
In your second example, head must've been 0x007ce390 before p1->next=nullptr, and it is still the same exact memory address after is assignment.
What your debugger is helpfully showing you is not just the pointer itself, the actual memory address it's pointing to, but also what are all the values the pointer references. Since p1 and head are now the same pointer, setting p1->next=nullptr also changes the values that head points to, and your debugger shows that.
But the pointer itself is unchanged.

Link based stack in C++

I've been trying to figure out how to create link based stack and came across a snippet of code that I don't quite understand.
int pop()
{
// If the stack is empty return a sentinel value
if (isEmpty())
return -999;
// Get the data to return from the top of the stack
int intReturn = top->info;
// Create a pointer to keep track of the top node
IntSLLNode *temp;
temp = top;
// Move the top of the stack to the next element
// or null if there is no next element
top = top->next;
// Free up memory
delete temp;
// Send back the data
return intReturn;
...
}
I understand up until top=top->next.
1) What was the point of creating a temp node if we never really use it?
2) By moving the top pointer to the next node, are we deleting the former top node? Thus popping it?
Thanks
1) temp is needed because we will need the old value of top after top is moved in order to free the memory of the node being popped. We have to move top then free the memory; if we try to do it the other way around (free memory, then move top) then we would have to use a temporary variable to hold top->next (as that would have been lost in this scenario). In either case, you can't avoid a temporary variable.
2) Moving top results in promoting the second node to the top node, and removing the top node from the stack (which is half of what we expect from pop - the other half being returning the value of the popped node). The node is not deleted until delete temp, which is why we needed to preserve it.

C++ trying to delete Binary Tree and move it to Vector

So I'm trying to write a function that places all of the values of a binary tree into a vector, which will later be used to recreate it. But when I try to call this function, I get an error:
Error in `./bst': double free or corruption (fasttop):
This is the function I'm using. The vector itself is a private variable containing nodes. size() returns the size of the tree and is working.
void BST::swapvector()
{
Node *ptr = m_root;
while (size() != 0)
{
if (ptr->m_left != NULL) {
ptr = ptr->m_left;
} else if (ptr->m_right != NULL) {
ptr = ptr->m_right;
} else {
Node *temp = ptr;
myvector.push_back(ptr); //starting from root, we traverse until we reach the bottom and then add ptr to the vector
ptr = m_root;
delete temp; //once we're finished, we delete temp
}
}
}
Does anyone know why this isn't working? Thanks!
It's obvious why this isn't working.
} else {
Node *temp = ptr;
myvector.push_back(ptr); //starting from root, we traverse until we reach the bottom and then add ptr to the vector
ptr = m_root;
delete temp; //once we're finished, we delete temp
}
You're storing a pointer to Node into vector and then deleting that Node with delete temp. After that pointer stored into vector points to garbage or non-existent memory.
"...a function that places all of the values of a binary tree into a vector..."
No, you're not storing binary tree values, you're storing pointers to binary tree values (Node objects).
There are two things you can do:
If the binary tree will not be freed nor changed for the lifetime of myvector then you can just remove the delete temp; line.
If assumption in the first case is not true, then you need to store Node elements into vector, not pointers to them. So, define myvector as vector<Node> myvector; instead of vector<Node *> myvector; and change myvector.push_back(ptr); to myvector.push_back(*ptr);.
You cannot delete temp after you place it a vector. Also, how is your vector defined? There might be problem there.
Also you should use iterators instead of push_back() function. It doesn't work well with pointers.
And, why does everyone insist on using c-style pointers. Use shared or unique pointers. Please?
Type of error usually signifies that a pointer being freed twice.

Create Dynamically Allocated Array with Pointers to Structs C++

So I currently have a simple struct (linkedlist) that I will be using in a HashMap:
struct Node {
std::string key, value;
Node* head;
}
I'm currently trying to dynamically allocate an array with pointers to each struct. This is what I have right now ...
Node* nodes = new Node[100]
I understand this allocates an array of 100 nodes into memory (which I will have to delete later on); however, upon iteration to try to transverse these nodes (which I an implementing as a linked list)...
for (int x = 0; x < 100; x++) {
Node current = nodes[x]; // Problem is I wanted an array to node pointers. This is not a pointer.
while (current != nullptr) { // this isn't even legal since current is not a pointer.
// DO STUFF HERE
current = current.next; // This is not a pointer access to a method. I'm looking to access next with current->next;
}
}
Hopefully I was clear enough. Can someone how to allocate a dynamic array of pointers to structs? So far I'm able to dynamically allocate an array of structs, just not an array of pointers to structs.
There are two approaches. Either you allocate an array of structures and introduce one more pointer that will point to the element in the array that will play the role of the head.
For example
Node *head = nodes;
(in this case head points to nodes[0])
After the list will not be needed you have to delete it using operator
delete [] nodes;
Or you can indeed to allocate an array of pointers to the structure like this
Node **nodes = new Node *[100];
But in this case each element of the array in turn should be a pointer to a dynamically allocated object;
And to delete the list you at first have to delete each object pointed to by elements of the array for example in a loop
for ( int i = 0; i < 100; i++ ) delete nodes[i];
and then to delete the array itself
delete [] nodes;
It is a good idea to initialize each element of the array with zeroes when the array is allocated for example
Node **nodes = new Node *[100]();
I suggested you this structure:
class myList {
struct Node {
string value;
Node* next;
}
/*Public methods .. Add/Set/Get/Next/isEmpty.. etc ... */
Node* head, *tail;
};
in main:
myList* lis = new myList[number];
then you have number of lists! and do all work in class by method's and operators, like if you want the next node just call lis[0].getNext();
if you want to skip current node dolis[0].Next(); ... etc ..
this how to work, what you try to do is looks like C program!