This is probably something really basic but I just can't seem to see where I'm messing up.
I've got a vector of Cubes (a child class of the abstract class Node) that each hold a body object that contains the x and z positions of its position on a plane. I'm attempting to move each in a "follow the leader" like style where the new position of a Cube is where the predecessor was before.
Since I'm using pointers this is where I'm a bit confused as at the moment, they are all going to the same position (wherever snake.x and snake.z is) so I know they are all pointing to the same piece of data.
Wonder what I need to alter so that each reflect the right coordinates.
void updateChildren()
{
Node * prevPiece;
typedef std::vector<Node*>::iterator It;
for(It curNode=nodes.begin(); curNode!=nodes.end(); ++curNode)
{
if (curNode == nodes.begin())
{
prevPiece = *curNode;
dynamic_cast<Cube*>(*curNode)->body.xPos = snake.xPos;
dynamic_cast<Cube*>(*curNode)->body.zPos = snake.zPos;
}
else
{
Node * tmp = *curNode;
dynamic_cast<Cube*>(*curNode)->body.xPos = dynamic_cast<Cube*>(prevPiece)->body.xPos;
dynamic_cast<Cube*>(*curNode)->body.zPos = dynamic_cast<Cube*>(prevPiece)->body.zPos;
prevPiece = tmp;
}
}
}
You assign the position of the the first Cube to the snake position, and then every subsequent Cube after that is just being assigned to this position.
Basically each iteration you are doing this:
current.position = previous.position.
previous = current; // The "previous position" has been overwritten
... next iterationn ...
current.position = previous.position; // previous.position is the new vlaue
previous = current;
...
You need to temporarily save the previous position before assigning it otherwise everything just get assigned to that.
You are modifying the head and then setting any subsequent element to the same values of the head.
A quick fix would be to do it the reverse way, from the bottom up, so that when an element is assigned a new value, we know that its old value is no longer needed. This is achieved using reverse_iterators:
void updateChildren()
{
for(auto curNode = nodes.rbegin(); curNode!=nodes.rend()-1; ++curNode)
{
dynamic_cast<Cube*>(*curNode)->body.xPos = dynamic_cast<Cube*>(*(curNode+1))->body.xPos;
dynamic_cast<Cube*>(*curNode)->body.zPos = dynamic_cast<Cube*>(*(curNode+1))->body.zPos;
}
dynamic_cast<Cube*>(nodes.front())->body.xPos = snake.xPos;
dynamic_cast<Cube*>(nodes.front())->body.zPos = snake.zPos;
}
Related
So I am currently working on a graph abstract data type for my CS163 class. Everything else for this program works awesome BUT the depth-first traversal of the graph. When testing, I add all the vertices I want, then connect them as I need to. I check and everything is indeed linked as it should be so we are good to go. I jump into this function below, given the name of the friend(vertex) to start from. The line I commented "*current_buddy = myQueue.front();" is the line I found in GDB to be the offending piece of code that causes a seg fault. Also using GDB, I was able to successfully print the proper vertex using "p myQueue.front()"
So perhaps a sample test to give a bit more context. say I have the points a,b,c,d, and e. a is connected to c,d, and e. b is connected to c. I want to start at vertex "a" for this test. Passing in a to the function, it finds the proper index with the find_location function which simply returns said index integer. It will then push that vertex onto the queue and mark that vertex as visited so that upon traversal, I don't return to that point to push it onto the queue again. I create a node "current" that is attached to the first node in the edge list for the "a" vertex. When it goes into the first loop, I use the previously created vertex "current_buddy" to point to the first object in the queue, which is the vertex "a." This is the point that the program hits a seg fault and I cannot for the life of me figure out what is going on with that line of code that would cause this.
Both "vertex" and "node" are structs I have created and the queue I am using is from the standard library #include queue more on the queue bit here if needed Any and all information would be greatly appreciated! Obviously since this is a school assignment, I don't expect anyone to just give me the answer but I am lost at the moment.
bool graph::breadth_first(char * start)
{
if(adjacency_list[0].buddy_name == NULL)
return false;
int location = find_location(start);
queue<vertex> myQueue;
myQueue.push(adjacency_list[location]);
adjacency_list[location].visited = true;
node * current = adjacency_list[location].head;
vertex * current_buddy = NULL;
while(myQueue.empty() == false)
{
*current_buddy = myQueue.front();//THIS LINE SEG FAULTS
cout << "THIS IS A FRIEND IN THE BREADTH-FIRST TRAVERSAL" << current_buddy->buddy_name << endl;
current = current_buddy->head;
myQueue.pop();
while(current != NULL)
{
if(current->connected_buddy->visited == false)
{
current_buddy = current->connected_buddy;
location = find_location(current_buddy->buddy_name);
myQueue.push(adjacency_list[location]);
adjacency_list[location].visited = true;
current = current->next;
}
}
}
for(int i = 0; adjacency_list[i].buddy_name != NULL; ++i)
{
adjacency_list[i].visited = false;
}
return true;
}
I don't know if this will work as you expect, but a quick fix might be to use the address-of operand and actually assign the pointer instead of dereferencing it:
current_buddy = &myQueue.front();
(EDIT: For the first part of this question, the solution/answer provided by Joachim may perform better. I just like avoid pointer when possible.)
You could try:
vertex * current_buddy = NULL;
while(myQueue.empty() == false)
{
vertex front_buddy = myQueue.front();
cout << "THIS IS A FRIEND IN THE BREADTH-FIRST TRAVERSAL" << front_buddy.buddy_name << endl;
current = front_buddy.head;
BTW - I think you need to check for null here:
while(current != NULL)
{
if (current->connected_buddy == NULL)
{
// add error handling
}
else
{
// normal code
}
}
So that you don't get another crash
This part
while(current != NULL)
{
if(current->connected_buddy->visited == false)
{
// your code
current = current->next;
}
}
looks like an endless loop in case current->connected_buddy->visited is true.
Maybe you want
while(current != NULL)
{
if(current->connected_buddy->visited == false)
{
// your code
}
// Moved out of the if-statement
current = current->next;
}
It's segfault because you are attempting to deference a NULL pointer.
vertex * current_buddy = NULL;
while(myQueue.empty() == false)
{
// V de-referencing a NULL pointer
*current_buddy = myQueue.front();//THIS LINE SEG FAULTS
You should change it to
// vertex * current_buddy = NULL; // < Remove this line
while(myQueue.empty() == false)
{
vertex *current_buddy = &myQueue.front();
I'm trying to implement an iterative deepening depth first search algorithm in C++. The search successfully finds the solution to the problem, but I am having trouble linking the child node back to the root node.
struct Node
{
std::vector<int> config;
int depth;
int action; //0 up 1 down 2 left 3 right
Node * parent;
bool operator<(const Node& rhs) const
{
return depth < rhs.depth;
}
};
As you can see in my structure, I have a pointer to the parent node. In my DFS code however, I am running into a problem updating the parent pointer for the nodes in each iteration of the loop. The parent pointer for all nodes always points to the same data location, 0xfffffffd2b0. In other words, the new node called Next is always created here.
I believe the Node I have in my code called Next always gets placed at this same data locataion, thus the reference location to each Next is always the same. How can I prevent it from always appearing at the same location? This means that the Child nodes are not being linked to their parent, but rather to themselves. I have marked the source of the bug with asterisks.
//IDDFS Logic:
int Current_Max_Depth = 0;
while(Current_Max_Depth < 20)
{
struct Node initial = {orig_config, 0, 0, NULL}; //config, depth, action, parent.
visited.clear();
priority_queue<Node> frontier;
frontier.push(initial);
while(frontier.size()>0)
{
struct Node Next = frontier.top();
visited.push_back(Next.config);
frontier.pop();
if(Next.depth < Current_Max_Depth)
{
int pos_of_hole = Find_Position_of_Hole(Next.config);
if(pos_of_hole==0)
{
std::vector<int> Down_Child = Move_Down(Next.config);
struct Node Down_Node = {Down_Child,Next.depth+1,1,&Next}; //****
if(!(std::find(visited.begin(), visited.end(), Down_Child)!=visited.end()))
{
if(Goal_Test(Down_Child))
{
goal_node = Down_Node;
goal_reached = true;
break;
}
frontier.push(Down_Node);
}
std::vector<int> Right_Child = Move_Right(Next.config);
struct Node Right_Node = {Right_Child,Next.depth+1,3,&Next}; //*******Passing next by reference here is not working since Next is always at the same data location. The nodes one layer up from the leaf nodes end up all pointing to themselves.
if(!(std::find(visited.begin(), visited.end(), Right_Child)!=visited.end()))
{
if(Goal_Test(Right_Child))
{
goal_node = Right_Node;
goal_reached = true;
break;
}
frontier.push(Right_Node);
}
}
if(pos_of_hole==1)
... does very similar for pos 1 through 8, not related to bug ...
} //End of if(Next.Depth < Max_Depth)
} //End of while(frontier.size()>0)
if(goal_reached)
{
break;
}
Current_Max_Depth++;
}
struct Node initial = {orig_config, 0, 0, NULL};
Creates a Node on the stack. When you create the next child
struct Node Down_Node = {Down_Child,Next.depth+1,1,&Next};
You are taking the address of that local stack object. When the loop ends Next is destroyed and then it is constructed again at the beginning of the next iteration of the while loop. If the nodes need to persist then you need to allocate them with new and then delete then when you are done.
On a side note the struct keyword is not required on variable declarations in C++. See Why does C need “struct” keyword and not C++? for more information.
I am working on a project where I create a double bounded pointer list, delete several elements, and still be able to read off the list. I have a double bounded pointer list, but am having trouble deleting elements and keeping the list double bounded. This then causes issues when trying to print the list.
Below is the IF statement I've placed in a while loop to help delete unwanted elements. I keep getting a segmentation fault (core dumped).
if ((black2 != black)||(white2 != white)) {
dump = help;
help = help ->next;
dump -> before = temp;
temp -> next = help;
help ->before = temp;
delete dump;
}//if
else { temp = help;
help = help->next;
help ->before = temp; }//else
To maintain properly the doubly linked list you should do something like :
void remove(X *elt) {
X* before = elt->before;
X* after = elt->next;
if (before != NULL) { // assuming first element points to NULL
before->next = after;
}
else {
first = after; // assuming first is a pointer to first element of list
}
if (after != NULL) { // assuming last element points to NULL
after->before = before;
}
else {
last = before; // assuming last is a pointer to last element
}
delete elt;
}
That way, you ensure that elements around current correctly point to each other dealing with special cases of removing first or last element.
But you already have a std::list template in Standard Template Library
One logical issue in your code is the line dump->before = temp.
What this does is that it sets the previous node pointer of dump to temp, as opposed to defining temp as the previous node.
The correct line should read temp = dump->before
PS: Your code is correct assuming that the node you are deleting isn't the first or last node (and you haven't padded with dummy nodes). You should introduce checks for these cases if required.
Having used the various search engines (and the wonderful stackoverflow database), I have found some similar situations, but they are either far more complex, or not nearly as complex as what I'm trying to accomplish.
C++ List Looping
Link Error Using Templates
C++:Linked List Ordering
Pointer Address Does Not Change In A Link List
I'm trying to work with Link List and Node templates to store and print non-standard class objects (in this case, a collection of categorized contacts). Particularly, I want to print multiple objects that have the same category, out of a bunch of objects with different categories. When printing by category, I compare an sub-object tmpCategory (= "business") with the category part of a categorized contact.
But how to extract this data for comparison in int main()?
Here's what I'm thinking. I create a GetItem member function in LinkList.tem This would initialize the pointer cursor and then run a For loop until the function input matches the iteration number. At which point, GetItem returns object Type using (cursor -> data).
template <class Type>
Type LinkList<Type>::GetItem(int itemNumber) const
{
Node<Type>* cursor = NULL;
for(cursor = first;
cursor != NULL;
cursor = (cursor -> next))
{
for(int i = 0; i < used; i++)
{
if(itemNumber == i)
{
return(cursor -> data);
}
}
}
}
Here's where int main() comes in. I set my comparison object tmpCategory to a certain value (in this case, "Business"). Then, I run a For loop that iterates for cycles equal to the number of Nodes I have (as determined by a function GetUsed()). Inside that loop, I call GetItem, using the current iteration number. Theoretically, this would let the int main loop return the corresponding Node from LinkList.tem. From there, I call the category from the object inside that Node's data (which currently works), which would be compared with tmpCategory. If there's a match, the loop will print out the entire Node's data object.
tmpCategory = "Business";
for(int i = 0; i < myCategorizedContact.GetUsed(); i++)
{
if(myCategorizedContact.GetItem(i).getCategory() == tmpCategory)
cout << myCategorizedContact.GetItem(i);
}
The problem is that the currently setup (while it does run), it returns nothing at all. Upon further testing ( cout << myCategorizedContact.GetItem(i).getCategory() ), I found that it's just printing out the category of the first Node over and over again. I want the overall scheme to evaluate for every Node and print out matching data, not just spit out the same Node.
Any ideas/suggestions are greatly appreciated.
Please look at this very carefully:
template <class Type>
Type LinkList<Type>::GetItem(int itemNumber) const
{
Node<Type>* cursor = NULL;
// loop over all items in the linked list
for(cursor = first;
cursor != NULL;
cursor = (cursor -> next))
{
// for each item in the linked list, run a for-loop
// counter from 0 to (used-1).
for(int i = 0; i < used; i++)
{
// if the passed in itemNumber matches 'i' anytime
// before we reach the end of the for-loop, return
// whatever the current cursor is.
if(itemNumber == i)
{
return(cursor -> data);
}
}
}
}
You're not walking the cursor down the list itemNumber times. The very first item cursor references will kick off the inner-for-loop. The moment that loop index reaches itemNumber you return. You never advance your cursor if the linked list has at least itemNumber items in the list.. In fact, the two of them (cursor and itemNumber) are entirely unrelated in your implementation of this function. And to really add irony, since used and cursor are entirely unrelated, if used is ever less than itemNumber, it will ALWAYS be so, since used doesn't change when cursor advances through the outer loop. Thus cursor eventually becomes NULL and the results of this function are undefined (no return value). In summary, as written you will always either return the first item (if itemNumber < used), or undefined behavior since you have no return value.
I believe you need something like the following instead:
template< class Type >
Type LinkList<Type>::GetItem(int itemNumber) const
{
const Node<Type>* cursor = first;
while (cursor && itemNumber-- > 0)
cursor = cursor->next;
if (cursor)
return cursor->data;
// note: this is here because you're definition is to return
// an item COPY. This case would be better off returning a
// `const Type*` instead, which would at least allow you to
// communicate to the caller that there was no item at the
// proposed index (because the list is undersized) and return
// NULL, which the caller could check.
return Type();
}
I've been working for hours trying to get this program to insert values into new nodes or "Player" structures for this program.
The thing is, this takes place inside function main(). My teacher requires me to insert as little code as possible since essentially "everything" is there which allows me to change it.
Here's the original code that stores each new value in the head while putting the older value inside "addNew":
Player * head = NULL;
for(int i=0; i<100; i++)
{
Player * addNew = (Player *)malloc(sizeof(Player));
if(head == NULL)
{
head->len = i;
Player * addNew = (Player *)malloc(sizeof(Player));
head->next = NULL;
}
addNew->next = addNew;
addNew->len = i;
}
Player * p = head;
//do this until 'p' has no address.
for(int i=0; p!=0; i++)
{
printf("%s ", p->str);
p = p->next;
}
Does anyone have any ideas on how to solve this?
IMPORTANT: My teacher would like me to not add any new variables or a tail. Please don't ask.
Update: Here's some older code:
//The head is the last one to hold a value. Therefore it gets pushed to the right.
Player * head = NULL;
Original Algorithm
for(int i=0; i<5; i++)
{
Player * addNew = (Player *)malloc(sizeof(Player));
printf("Insert a string: ");
scanf("%s", addNew->str);
addNew->next = head; //assign head's current address to addNew->next
head = addNew; //assign all of addNew to head
}
Update: Here's a new implementation which doesn't work. I can't really find out where exactly that other for loop should go.
addNew->ID = 1;
addNew->ID += i;
if(head == NULL)
{
head = addNew;
addNew->next = head; //assign head's current address to addNew->next
//head->next = addNew;
}
//head->next = addNew;
addNew->next = head;
//head = addNew; //assign all of addNew to head
printf("%d\n", addNew->ID);
Simple trick: have the list* always point to the last element in the list. And set that last element's next pointer to the start of the list. Now you can always easily find both the start and the end of the list with just one pointer. The start is at list->next. Don't call it tail, just "list".
Right now, you're adding everything to the head of the list. However, you want to add to the tail instead.
You already have a pointer to the head. In addition to that though, you'll also need a pointer to the tail. Can you think of a way to get (and update) it?
You could save a pointer to the tail of the list and instead of saving the next item on each node, save the previous one.
This might not be an option but I thought I'd suggest it anyway. Instead of storing things in a different order, you could leave things stored as they are, but simply change the way you output the values. This would not only be very simple to implement, it would also be a faster during list inserts.