Reputation: 47
i asked a similar question here yesterday and i corrected some of the issues but the main one still persists.
Im enqueuing and dequeueing Position objects into a Position queue.As i enqueue 2 different Position objects, and dequeue both back out, both Position objects that are returned have the same value as the 2nd object put in. When i check the values that have been enqueued inside the enqueue function they are correct.I dont understand how this wont work as ive worked out the logic and used the dequeue algorithm verbatim from a book;
The Position class has 3 array based stacks as private members
struct Posnode
{
Position *pos;
Posnode *next;
};
class Position
{
private:
Posnode *front,*back,header; //front = back = &header;
Pegs A,B,C;
Position::Position(int num): A(num), B(num), C(num)
{
front = back = &header;
A.assignpeg(num);//assigning 1 to n to each Peg
B.assignpeg(num);
C.assignpeg(num);
}
#include "Pegs.h"
#include "Position.h"
int main ()
{
Position pos(4), intial(3),p,m,n;
intial.geta();//poping Peg A stack
pos.getc();//poping Peg c stack
p.enqueue(intial);
p.enqueue(pos);
p.dequeue(m);//position 'pos' is returned rather than intial
p.dequeue(n);//position 'pos' is returned
cin.get();
return 0;
}
void Position::dequeue(Position&)
{
Position p;
Posnode *ptr=front->next;//front points to an empty node wi
p = *ptr->pos;//assigning the position in ptr to p
front->next = ptr->next;
if (back == ptr) {//if im at the end of the queue
back = front;
}
delete ptr;
return ;
}
void Position::enqueue(Position n)
{
Posnode *ptr = new Posnode;
ptr-> pos = &n;//copying Position n calls Pegs operator =
back->next = ptr;//values that are enqueued check back ok
back = ptr;
return;
}
Pegs& Pegs::operator=(const Pegs & ori)//Pegs copy contructor
{
top=-1;
disks = ori.disks;
peg = new int[disks];
int element=0,g=-1,count=0;
while (count <= ori.top)//copying elements if there are any in ori
{
++count;
element=ori.peg[++g];
push(element);
}
return *this;
}
Upvotes: 3
Views: 400
Reputation: 6329
Sorry mate, but there are many problems with your code. Some of them seem to be copy/paste errors, but other show lack of C++ understanding. I'll focus on the latter first.
The member function void Position::enqueue(Position n)
copies all passed arguments by value. So what happens when you call it? The parameter is copied and inside the function you are dealing with this copy that will be disposed when the function's scope ends. So assignemtn ptr-> pos = &n
will assign an address of a temporary object to pos
. Data at the address of disposed object may still be valid for some time, as long as nothing writes over it, but you should never ever depend on this behaviour. What you should do is you should pass the parameter by reference, i.e. change the declaration to void Position::enqueue(Position& n)
. That way the actual object will be passed, not a automatic copy.
If you don't specify a name for an argument like in void Position::dequeue(Position&)
, you won't have access to it. Inside this function you create a local variable p
and then assign the result to it. But because p
is local it will be disposed when the function returns. Needless to say, the parameter that you pass to this function is inaccessible because it's unnamed. What you should do is you should declare the function like that: void Position::dequeue(Position& p)
.
As a good advice: you should do better job with isolating your case. For example, are Pegs
connected in any way to the problems you are having? Also avoid declarations like Posnode *front,*back,header
- in most cases they make code harder to read. And did you notice that your code has #include
s inside class body?! You should never to that, except for times when you exactly know what you are doing. #include
directives should be usually put in the first lines of a source file.
Upvotes: 1