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);
Related
I have a Node class, and when I created an array of Node pointer(Node*) and passed it through the method, I had a different length of the array as the parameter.
Node* hands[4];
Deal(deck,hands,4,"one-at-a-time",13);
void Deal(Node* &deck, Node* hands[], int people, std::string type, int count){
Node*& temp = deck;
for (int i = 0; i < count; ++i) {
for (int j = 0; j < people; ++j) {
append(hands[j], CopyDeck(temp));
temp = temp->after;
}
}
}
When I use Clion debugger to see the value of variables, I found that hands that I create has values of
hands[0] = 0x746365667265700e
hands[1] = NULL
hands[2] = NULL
hands[3] = 0x00007fc44b402430
And when it is passed through the method, in method the hands is
*hands=0x746365667265700e
hands[1]=NULL
hands[2]=NULL
hands[3]=0x00007fc44b402430
hands[4]=0x00007fc44b402570
What does the "*hands" stand for? And why the initial value in hands are not NULL? Actually the minimal example I can have is something like:
class Node{};
void test(Node* list[]){}
int main(int argc, char* argv[]){
Node * temp[4];
test(temp);
}
But it works. And I have already written the same code in other files and works as I thought.
The deck is a simply doubly-linked list of Node. Node has an attribute "after" point to the next Node. My debugger told me before
Node* &temp = deck;
the parameter "hands" already becomes a 5 elements array.
I think I found a possible reason but I can't understand the relationship between. There are two test methods in my main function. The first one is called "SortingTest" and the second one is "DealingTest". When I comment the first test method out, my DealingTest works properly, but after I uncomment it, the DealingTest doesn't work. After SortingTest ends there is no attribute or anything left in the main method. Can anyone explain it to me? Thank you all. Or maybe my clear method is wrong so it not frees the memory correctly?
void DeleteAllCards(Node* root){
Node *current, *next;
current = root;
while (current != nullptr){
next = current->after;
delete current;
current = next;
}
}
The array you created is a C-Style array, which is a fixed size array with 4 elements. In your case, the element type is Node pointer.
C-Arrays do not initialize with default values, unlike many other popular languages. Therefore, the pointer values you are seeing in hands are either a pointer to a Node * or derived type or a garbage memory address with some exceptions to this rule (see below for the edge cases defined by the Standard. For the ones that do say NULL, their memory address is at ox0000...
Update Edit To reflect a comment made by #AlgirdasPreidZius -
For C and C++, there is a standard rule where a standard C-Array shall be populated with default values upon initialization. C++ standard section 6.8.3.2.2 ([basic.start.static]): "If constant initialization is not performed, a variable with static storage duration or thread storage duration is zero-initialized."
As to why your array has those values in them from the function provided, we need more context. A reproducible example is always the best.
Your for loop, judging by the passed in parameters, is an N^2 time complexity loop with 4*4 iterations. The C-Array Node * was also passed in by reference, so when you assign Node *& to deck, the memory address marking the start of the array changes to the location of the deck array. So, it will have the values that the deck C-Array of Node *'s contains, assuming copy is a 1 : 1 copy, deep or shallow
I have problem with c++ pointer delete and re allocation. please give me a idea about this two method. I have no chance to use smart pointers.(This is not an actual code- I should replace reference type with int)
#include <iostream>
#include <queue>
using namespace std;
int main() {
queue<int*>q;
int* a= new int(5);
q.push(a);
/* 1. method */
while (!q.empty()) {
int* x = q.pop();
....do something...
delete x;/* is here deleting the firstly created int a object? */
/* or only deleting newly created allocation of *x? */
}
/* 2. method */
int* x = q.pop();
while (!q.empty()) {
....do something...
*x = q.pop();
}
/* here i'm reallocating the values for x. is here deleting firstly created int a object? */
/* is 2 method = 1 method ? */
return 0;
}
delete x;/* is here deleting the firstly created int a object? */
Yes. The new call allocated memory and returned a pointer, which you pushed onto your queue. You then (tried to) pop the value into x. You can copy pointers around as much as you want, but they are only allocated and deleted once.
/* or only deleting newly created allocation of *x? */
What? No. Whatever you were trying to ask, the answer is no. The question is troubling.
/* here i'm reallocating the values for x. is here deleting firstly created int a object? */
No, you are not "reallocating the values for x". Assuming this code compiles (which it doesn't), but assuming that it does what it's obvious you thought it should do, then the answer is no. You also do not delete the "firstly created int a object".
What happens is you leak the memory for the original value stored in a (and subsequently pushed to your queue) because you never delete it. Furthermore, the queue is empty after the first pop and you never enter the loop.
But if you did enter the loop, you have a type conflict where you are now storing the pointer you just popped into the integer-sized memory location you originally allocated in a and popped out into x. Your compiler should warn you about this.
Now let's suppose you instead say (and here I'm also showing you the correct way to access and pop from std::queue):
x = q.front();
q.pop();
Now you have still leaked the old value of x because you did not store it anywhere else and did not delete it. And you have replaced it with the next value in the queue, which you also don't delete and so you also presumably leak.
/* is 2 method = 1 method ? */
No. Method 1 is the most correct, but you still have it wrong. You meant:
while( !q.empty() )
{
int *x = q.front();
q.pop();
// do something...
delete x;
}
I have declared a basic structure as below.
struct Item
{
MPoint key; //4 element double array x,y,z,w represents a point in space
Item * next = NULL;
};
I have a small array of pointers to these structures
Item * arr[3];
When an item is created, the key is defined by its location which is a unique point in 3D space.
Item hti; //create a new item struct called hti
hti.key = transf.rotatePivot(MSpace::kWorld);
Item * p_hti = &hti; //pointer to the struct
arr[0] = p_hti;
The main problem is that when i watch the arr[0] variable in my debugger, it shows the correct key values. However, as soon as I examine the data as in
double x = arr[0]->key.x;
Instead of getting the correct value for x, i get x = -9.2559631349317831e+61 every time and for all the other values in the key (x,y,z).
I assume that the strange value above represents memory that is uninitialized but it just doesn't make sense to me how the array correctly holds the value up until I try to pull the value back.
Any help would be appreciated!
In your example where you write:
Item hti; // declared on the stack
// ...
Item* p_hti = &hti; // points to item on the stack
arr[0] = p_hti; // points to item on the stack
You are causing this array to reference items that are in the current stack frame and which will be undefined after leaving this stack frame (or which could be corrupted if you perform an operation that corrupts the current stack). Is your dereference of this array happening in the same function? Or does it happen after you return "arr" from the function in which you initialized it? If the latter, that would explain your problem... the memory it references has gone out of scope. To prevent that issue, you should use dynamic memory allocation (with new) in initializing your array (you'll also need to remember to deallocate that after you are done with it with a corresponding delete).
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.
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.