struct node
{
char *ptr = (char *)malloc(frames*sizeof(char));
}*start,*current;
Then I have allocated memory equal to node to start.
[...]//Assigned values to start node.
current = start;//Current points to start
node *temp = new node();//temp will point a newly created node
*temp = *current;// COPYING VALUES OF CURRENT TO TEMP
[...]
I want to create a new node, make temp point to it and copy values of current (here current is pointing to start) to temp.
BUT this is making temp point current (here start) instead.
Frustrated. Where am I going wrong?
*temp = *current should be temp = current.
There could be two solutions
Change *temp=*current to temp=current. Doing this, you can access values of "current" using "temp" as these two pointers are now referring to the same memory location. Caution, changing value by using "current" or "temp" will cause to change in value in both pointers as they are referring to same memory location.
Use memcpy. It will copy values from one memory location to other. Here is the reference. Now you have two independent copies of values.
Related
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.
I have a pointer to a node in a linked list:
struct node *temp = head.next
If I set this pointer equals to NULL such as:
temp = NULL;
will this also affect the node I was pointing to? i.e. head.next is now NULL?
will this also affect the node I was pointing to? i.e. head.next is now NULL?
No.
Think of it this way. head.next is a variable holding a value (address). When you do
struct node *temp = head.next
Now temp also has the same value as head.next.
Later when you change the value of temp, why should the value held by head.next change.
This is the difference when you copy the value of a variable (which is happening is this case), and when you make a variable refer to some other variable, and change its content.
If you want the latter then you need a pointer to pointer to struct node
Something like
struct node **temp = &head.next;
Now if you want to change the content of head.next also through temp you can do by
*temp = NULL;
No it will not. You have to understand the when you update a pointer you don't update its content or the memory location it was pointing to. For that you have to explicitly do it.
Now for your problem:
temp is holding an address of memory location where head->next resides. Something like (0x980901) setting it to null will only change the address it was pointing ie. now it will point to nothing.
Let me explain this to you using an anology. Suppose you have a piece of paper and upon it you have written address of your friends house. You erase the content written on this piece of paper does that mean you friend was moved out of his house? Obviously not.
In your case this piece of paper is temp pointer.
No, because you didn't change the content of the pointer.
You just told him to point on something else.
All of the above answers are very well explained but may be confusing to people who have just started learning pointers.
Both temp and head.next are variables of type struct node *. Just forget pointers for a second and think about your question if both of struct node * variables where just int.
See this analogy:
int a = 1;
int b = a;
b = 0;
// a remains 1, b is 0
Now back to your question:
struct node* head.next = 1; // Some initial value
struct node* temp = head.next; // temp now has the value of 1
temp = NULL; // temp assigned the value of NULL, variable head.next remains unchanged
There is nothing magical or special with pointers, they follow the same rules as any other variable type.
Consider:
int x = 5;
int y = x;
y = 0;
The y = 0; will of course not change the value of x. The very same applies to your example.
I think you are somehow confusing this with changing the contents of a pointed-to variable. If you would instead do
int x = 5;
int* y = &x;
*y = 0;
Then *y = 0; would change x. But y would remain unchanged - it is still pointing at x
I have following problem:
I have this method in class Tree:
Node * nearest(const Point & point) const{
double minDistance = numeric_limits<double>::max();
Node * nearest = new Node;
for(Node *n : nodesVector){
int actualDistance = point.distance(n->point);
if(minDistance > actualDistance){
nearest = n;
minDistance = actualDistance;
}
}
return nearest;
}
This method is called from another class as follows:
void extend(const Point & rand){
Node *xNear = this->tree.nearest(rand);
Node *xRand = tree.add(rand, xNear);
std::vector<Node *> xNearSet = tree.rNearest(rand, this->RADIUS);
for(Node *node : xNearSet){
double c = node->cost + node->point.distance(rand);
if(c < xRand->cost){
xRand->parent = node;
}
}
for(Node *node : xNearSet){
double c = xRand->cost + node->point.distance(rand);
if(c < node->cost){
node->parent = xRand;
}
}
}
I need my method nearest and extend to not change variables in the tree after the extend execution, particularly the nearest node.
So I assumed that using pointer would make this for me, but unfortunately it has not so I have tried to create new pointer to Node, but this approach is not working for me either.
I would like to ask how can I implement it to not change the original node (use only it's copy that won't be treated as local variable or referenced the original one) that is used as nearest?
Thank you in advance for any suggestions.
EDIT:
Maybe I'll little bit reformulate the question. Now I have removed the memory leak, the line :
Node * nearest = new Node;
by line:
Node * nearest = nullptr;
But the main problem was and still is that after the local variable Node *xNear disappears then there are weird values assigned to the original node that was pointed by nearest.
Once you assigned nearest = n; the nearest variable no longer points at the newly created object, but to the one found in the nodesVector collection – and that one is returned.
if you want to return a copy, then don't overwrite nearest with an n pointer but rather assign values to the object pointed at:
*nearest = *n;
(be sure you have proper assignment operator defined in the Node class). This way you will return a copy of the nearest object.
So the biggest problem was that there was incorrectly initialized the initial nearest from the constructor (as a local variable without new) so it's values were somehow rewritten to some weird values. It has happened only at the time when there was as a xNear found the initial first from the Node values.
I guess your troubles are related to other operations in your code. How does Tree::add() work in your implementation? How is the tree populated in the first place?
My guess is that nearest is now in two locations in the tree, or a parent pointer is pointing to the same object it originates from.
Look at your tree in a debugger and navigate all the pointers. Additionally print every pointer in the destructor of Node to see whether you are pointing to free memory. Set a breakpoint there to find which scope was exited when the destructor was called.
It is difficult to understand how this node is being created, Can you please write step-wise what this set of code is actually doing, and what actions they represent?
void list::create_node(int value)
{
struct node *temp;// Please write in words the meaning of this statement
temp = new(struct node);// is this a dynamic node? )
temp->info = value;// is this value being assigned to this node?
if (last == NULL)// what is this set of code testing??
{
last = temp;// who is this last; the node which has been created?
temp->next = last; // is the node pointing to itself being only one node?
}
else
{
temp->next = last->next;((( // What is this statement saying?
last->next = temp;// What is this statement saying?
last = temp;// What is this statement saying?
}
}
void list::create_node(int value)
{
The above line declares a function that creates a node with the given value and inserts the node into the list. The code must be examined to see where the new node is inserted.
struct node *temp;
Declares a pointer to a node. The memory has not been allocated yet, only a pointer that will be used later.
temp = new(struct node);
Allocates memory for a node from the dynamic (runtime) memory area (a.k.a. heap). Calls the constructor of the node structure to initialize the memory, if a constructor exists.
The pointer temp is now pointing to the node object.
temp->info = value;
This assigns the value to the data field, info. Need the declaration of struct node in order to confirm this guess.
if (last == NULL)
{
Assuming that last is a pointer and points to the last node, this check is looking for an empty list. Common implementation is to have pointer values set to null to mark the end of the list.
last = temp;
temp->next = last;
}
The above code inserts the new node as the last node. The last pointer allows fast access to the end of the list. This allows for reverse iteration without having to traverse all the links to find the last node.
Some implementations set the next field to null to indicate the end of the list, others like this one, make it point to the last node.
else
{
temp->next = last->next;
At this point, the list is not empty.
The new node is made to point to the same node that the last node points to.
This is best understood by drawing the node boxes and arrows pointing to the nodes.
last->next = temp;
Updating the last node to point to itself. See the above section.
last = temp;
Updating the pointer to the last (end of list) node to point to the new node.
}
}
I suggest you draw the linked list and walk through this algorithm a couple of times to see how it works. Also review the singly linked list data type.
The circular reference of the last node may be confusing to you. This may not be the standard implementation that most books describe, but it is valid.
My problem is q->next always prints the same address, but I assigned q = &x;. Why it is not printing different addresses?
#include <stdio.h>
class Node
{
public:
int val;
Node *next;
Node(int v,Node *p) { val=v, next=p; }
};
int main()
{
Node head(0, NULL);
Node *q = &head;
int i = 5;
while (i>0)
{
Node x(i * 10, q);
q = &x;
printf("# %d %p\n", q->val, q->next);
i--;
}
}
In the first iteration of the loop, q contains the address of head. On each subsequent iteration, q contains the address of x.
This means that on the first iteration, q->next yields the address of head and on each subsequent iteration, q->next yields the address of x. However, x is created inside the loop, on the stack. Since there is no change to the stack inbetween, the x object always appears at the same place on the stack.
So I'd expect the program to print first the address of head and then four times the address of the four x objects (which all happen to be allocated at the same position of the stack).
I think the reason is that, within the while loop, you declare x on the stack. Then after the end of the while loop has been reached, the variable gets "destroyed". In the subsequent iteration, however, x gets reserved on the stack again using the exact same (stack) memory place.
Note that you won't get a linked list with valid pointers. You need to create Node instances on the heap using 'new' operator.
EDIT:
If you don't want to allocate memory on the heap you can use the "Linked lists using arrays of nodes" approach descriped here. The drawback is, however, that you need to know the maximum number of nodes in advance.
This has to do with the way x is allocated: It is a local variable inside the main function. That means it is allocated on the stack, at a specific position. You are reusing the same piece of memory all the time. Instead, try allocating memory for new nodes (new).
Your are creating the Node on the stack - try using new.
x is a local variable in the while loop. Its lifetime is only one iteration of the loop.
You should dynamically allocate the Node objects like so :
Node* x = new Node(value, next);
so their lifetime lasts until you de-allocate the object :
delete x;
Node x is being created on the stack, each time you go round your loop it will be getting created and then destroyed again at the end of the block. And each time round the loop it will be being created in the same location.
You probably want:
Node *x = new Node( i*10, q );
q = x;
You keep setting next to q:
Node x(i * 10, q);
Your x node is allocated on the local stack, not on the heap, so as your variable gets recycled on each loop iteration it recieves the same local address. To create i = 5 uique nodes you need to allocate object on heap using new() operator. You would also to add code to destoy your allocated objects afterwards.
example:
Node * px = new Node(i*10, 1);