C++ Tree pointer Error - c++

I am trying to figure out how to create a tree in C++. I have tried debugging this for hours and I thought it was time I got another set of eyes on it. My question is if my treeNodeClass looks correct. Right now I am getting a stack explosion because I'm double removing items from my node. The tree itself will be parsing a simple xml file. Here is my code.
#include "treeNodeClass.h"
TreeNodeClass::TreeNodeClass()
{
cout << "TREENODECLASS::TREENODECLASS()" << endl;
attributes.clear();
children.clear();
data = "";
height = 0;
parent = NULL;
tag = "";
cout << "EXIT TREENODECLASS::TREENODECLASS()" << endl;
}
TreeNodeClass::TreeNodeClass(const TreeNodeClass& other)
{
cout << "TREENODECLASS::TREENODECLASS(const other)" << endl;
parent = NULL;
CopyIntoMe(other);
cout << "EXIT TREENODECLASS::TREENODECLASS(const other)" << endl;
}
TreeNodeClass::~TreeNodeClass()
{
cout << "TREENODECLASS::~TREENODECLASS()" << endl;
if(parent)
delete parent;
parent = NULL;
children.clear();
attributes.clear();
cout << "EXIT TREENODECLASS::~TREENODECLASS()" << endl;
}
void TreeNodeClass::CreateAttrib(string root, string val)
{
string attrib = root + "=" + val;
attributes.push_back(attrib);
}
void TreeNodeClass::CreateTag(string data, string name)
{
tag = name;
this->data = data;
}
list<string> TreeNodeClass::ReturnAttrib()
{
return this->attributes;
}
string TreeNodeClass::ReturnTag(string tag)
{
string retTag = "";
if(this->tag == tag)
retTag = this->tag;
return retTag;
}
void TreeNodeClass::AddChildren(TreeNodeClass* c)
{
if(c != NULL)
children.push_back(c);
}
TreeNodeClass& TreeNodeClass::operator=(const TreeNodeClass& other)
{
cout << "TREENODECLASS& TREENODECLASS OPERATOR = " << endl;
if(&other != this)
{
if(parent)
delete parent;
parent = NULL;
attributes.clear();
children.clear();
CopyIntoMe(other);
}
return *this;
}
void TreeNodeClass::CopyIntoMe(const TreeNodeClass& other)
{
cout << "Copy into me" << endl;
tag = other.tag;
data = other.data;
attributes = other.attributes;
children = other.children;
parent = new TreeNodeClass;
parent = other.parent;
height = other.height;
}
void TreeNodeClass::AddParent(TreeNodeClass* p)
{
if(p)
{
parent = new TreeNodeClass;
parent = p;
}
}
std::vector< TreeNodeClass* > TreeNodeClass::ReturnChildren()
{
return children;
}
ostream& operator<<(ostream& out, const TreeNodeClass& treeNode)
{
out << "NODE: " << treeNode.tag << " " << treeNode.data << endl;
out << "CHILDREN: " << treeNode.children.size() << endl;
out << "HEIGHT: " << treeNode.height << endl;
out << "Attributes: ";
for(list<string>::const_iterator iter = treeNode.attributes.begin(); iter != treeNode.attributes.end(); iter++)
{
out << *iter << " ";
}
out << endl;
}
void TreeNodeClass::SetHeight(int h)
{
height = h;
}
/*void function(TreeNodeClass* node)
{
cout << node << " " << *node << endl;
}
TreeNodeClass* function2(TreeNodeClass* node)
{
return node;
}
int main()
{
cout << "STARTING PROGRAM" << endl;
cout << "CREATING A TREE NODE CLASS " << endl;
TreeNodeClass* newNode;
TreeNodeClass* tempNode;
list<string> attribs;
newNode = new TreeNodeClass;
tempNode = new TreeNodeClass;
newNode->SetHeight(10);
cout << *tempNode << " " << *newNode << endl;
tempNode->SetHeight(20);
cout << *tempNode << "\n " << *newNode << endl;
cout << "Setting equal " << endl;
*tempNode = *newNode;
cout << *tempNode << " " << *newNode << endl;
tempNode->SetHeight(40);
cout << *tempNode << " " << *newNode << endl;
tempNode->AddChildren(newNode);
newNode->AddParent(tempNode);
cout << *tempNode << "\n " << *newNode << endl;
return 0;
}
*/
And I'm trying to use this code on a simple state machine. I basically set up a vector of lists to return the states. This is what I believe is giving me a majority of my errors. I've been staring at this as well for a while, but I'm kind of lost.The machine will create the tree (supposedly). When the state machine finishes (state 10) it returns and the calling function will just make another call to yylex(). Thanks for the help so far!
TreeNodeClass* ProcessTree(TokenT token, vector <list <stateAssoc> >& vecTree, int depth)
{
int state = 1; //Assume this is a new record.
bool noState = false;
bool update = true;
int dex = 0;
string root, value, data, tag;
TreeNodeClass* treeNode;
treeNode = new TreeNodeClass; //Assume a new node per state machine visit.
while(state != 10)
{
switch(state)
{
case 1: dex = 1;
break;
case 2: state = 3;
noState = true;
root = yylval;
break;
case 3: state = 4;
noState = true;
break;
case 4: dex = 3;
value = yylval;
//cout << value << endl;
treeNode->CreateAttrib(root, value);
break;
case 5: dex = 2;
data = yylval;
//cout << 5 << " " << yylval << " " << token << endl;
//If its data store as data; if tag its a start tag.
break;
case 6: dex = 4;
//cout << token << " " << yylval << endl;
break;
case 7: state = 9;
noState = true;
tag = yylval;
//cout << tag << token << endl;
if(data != "" and data != "authors")
treeNode->CreateTag(data, tag);
break;
case 8: {
TreeNodeClass* childNode = new TreeNodeClass;
childNode = ProcessTree(token, vecTree, depth+1);
cout << "BEFORE PARENT" << endl;
childNode->AddParent(treeNode);
childNode->SetHeight(depth);
treeNode->AddChildren(childNode);
delete childNode;
childNode = NULL;
}
token = TokenT(yylex()); //Get a new token to process.
dex = 5;
break;
case 9: state = 10;
noState = true;
update = false;
break;
case 10: noState = true;
update = false;
break;
default: cout << "Error " << endl;
cout << state << endl;
cin.get();
break;
}
if(!noState)
state = FindMatch(vecTree[dex], token);
else
noState = false;
if(update)
token = TokenT(yylex());
else
update = true;
}
return treeNode;
}

1.A children shouldn`t delete a parent:
TreeNodeClass::~TreeNodeClass()
{
cout << "TREENODECLASS::~TREENODECLASS()" << endl;
/* Delete next 2 lines
if(parent)
delete parent;
*/
parent = NULL;
children.clear();
attributes.clear();
cout << "EXIT TREENODECLASS::~TREENODECLASS()" << endl;
}
2.Containers will not delete a pointer -- you should take it in mind always. Easy way to delete, for example:
for (vector<TreeNodeClass*>::iterator child = children.begin(); child != children.end(); ++child)
delete *child;
But best way -- not use native pointers and use some smart pointers or shared pointers.
3.Main function do not delete pointers tempNode and newNode.
4.If you'll use native pointers, you should recursively create and copy each children. In other way you'll catch memory leak.
5.Example of method CopyIntoMe:
void TreeNodeClass::CopyIntoMe(const TreeNodeClass& other)
{
cout << "Copy into me" << endl;
tag = other.tag;
data = other.data;
attributes = other.attributes;
// delete each pointer to Nodes
foreach (vector<TreeNodeClass*>::iterator child = children.begin(); child != children.end(); ++child)
delete *child;
children.clear();
// Copy recursively each child
foreach (vector<TreeNodeClass*>::iterator child = other.children.begin(); child != other.children.end(); ++child) {
TreeNodeClass* new_child = new TreeNodeClass;
new_child->CopyIntoMe(*child);
children.push_back(new_child);
}
parent = other.parent;
height = other.height;
}

This is bad:
parent = new TreeNodeClass;
parent = p;
This is a memory leak. Since you are allocating memory and pointing parent to it, then immediately pointing parent to something else, you can never delete that allocated memory. The memory will be allocated and lost every time AddParent() is called.

Related

I've done a program to display student name and height using queue linked list in C++ now i want to display it in Desceding order i dont know how

using namespace std;
void createsqueue();
void insertname();
void insertheight();
void del();
void push();
void display();
struct nodename
{
string name;
float height;
struct nodename *next;
};
nodename *front;
nodename *rear;
void createstack()
{
front = NULL;
rear = NULL;
}
void insertname()
{
while (true)
{
char dec;
nodename *temp;
temp = new nodename;
std::cout << "ENTER YOUR NAME : ";
std::cin >> temp -> name;
std::cout << "ENTER YOUR HEIGHT : ";
std::cin >> temp -> height;
std::cout <<'\n';
temp -> next = NULL;
if(rear == NULL)
{
rear = temp;
front = temp;
}
else
{
rear -> next = temp;
rear = temp;
}
std::cout << "ADD ANOTHER DATA? (Y/N) : ";
std::cin >> dec;
std::cout <<'\n';
if (dec == 'n' || dec == 'N')
{
break;
}
}
}
void del()
{
if(front != NULL)
{
nodename *temp = front;
cout << "The deleted element is: " << temp -> name << endl;
front = front -> next;
delete temp;
}
else
{
cout << "Queue List is empty!\n";
}
}
void display()
{
nodename *temp = front;
while(temp != NULL)
{
std::cout << "--------------------------" << '\n';
std::cout <<"NAME : "<< temp -> name << endl;
std::cout << showpoint << fixed << setprecision(0);
std::cout <<"HEIGHT : " << temp -> height << endl;
std::cout << showpoint << fixed << setprecision(2);
temp = temp -> next;
std::cout << "--------------------------" << '\n';
}
}
int main()
{
int operation;
createstack();
do
{
std::cout << "\tMAIN MENU" << endl;
std::cout << "1 - ENTER NAME : "
<< "\n2 - DELETE PREV DATA : "
<< "\n3 - DISPLAY DATA : "
<< "\n0 - End Program"
<< "\nEnter your operation: ";
cin >> operation;
switch (operation)
{
case 1: insertname();
break;
case 2: del();
break;
case 3: display();
break;
case 0: cout << "Program End";
break;
default:
cout << "Wrong option. Please insert a new operation: ";
}
}
while(operation ! = 0);
return 0;
}
This is the code.
The program Works fine the only problem I have is displaying the name with height in descending order so that the tallest person's info displays first
I have tried multiple ways but nothing seems to work it might be my in-experience in coding since im a newbie and pardon me for any error im just getting started
Modify the code for inserting a new name such that whenever you add a node,you find the correct position for it before inserting in the linked list.
void insertname(){
cin>>h;
nodename* ctr=front;
while(ctr-> height >h){
ctr=ctr->next;
}
nodename* temp =new nodename;
temp->next=ctr->next
ctr->next=temp
temp->height=h; //similarly for name
}
Just find it if the node added is the first node or any other which you have achieved and the above will add nodes in the descending order, which will be displayed as you wanted. So, you can modify it accordingly.

C++ Sorted Doubly Linked List: Problems inserting in middle of list

below is my current in-progress code converting a singly linked to a doubly linked list. I haven't touched the delete function yet. I've gotten insert in empty list, end of list, and beginning of list apparently working.
However nodes inserting in the middle seemingly fail to create a link to the previous node. My debugging lines I inserted seem to show both the n->next and n-> prev with the correct memory address, but when I go to reverseprint, any nodes inserted in the middle are missed and the links are gone. Where am I going wrong in regards to this?
Code below:
#include <iostream>
#include <string>
using namespace std;
// define a node for storage and linking
class node {
public:
string name;
node *next;
node *prev;
};
class linkedList {
public:
linkedList() :top(NULL) {}
bool empty() { return top == NULL; }
node *getTop() { return top; }
node *getEnd() { return end; }
void setTop(node *n) { top = n; }
void setEnd(node *p) { end = p; }
void add(string);
int menu();
void remove(string);
~linkedList();
void reversePrint();
friend ostream& operator << (ostream&, const linkedList&); // default output is in-order print.
private:
node *top;
node *end;
};
void main() {
linkedList l;
cout << l.empty() << endl;
int option = 0;
string s;
bool go = true;
while (go) {
option = l.menu();
switch (option) {
case 1: cout << "enter a name: "; cin >> s; l.add(s); break;
case 2: cout << "enter name to be deleted: "; cin >> s; l.remove(s); break;
case 3: cout << l; break;
//case 4: cout << "can not be done with a singly linked list" << endl;
case 4: l.reversePrint(); break;
case 5: cout << "exiting" << endl; go = false; break;
}
}
system("pause");
}
void linkedList::remove(string s) {
bool found = false;
node *curr = getTop(), *prev = NULL;
while (curr != NULL) {
// match found, delete
if (curr->name == s) {
found = true;
// found at top
if (prev == NULL) {
node *temp = getTop();
setTop(curr->next);
delete(temp);
// found in list - not top
}
else {
prev->next = curr->next;
delete(curr);
}
}
// not found, advance pointers
if (!found) {
prev = curr;
curr = curr->next;
}
// found, exit loop
else curr = NULL;
}
if (found)cout << "Deleted " << s << endl;
else cout << s << " Not Found " << endl;
}
void linkedList::add(string s) {
node *n = new node();
n->name = s;
n->next = NULL;
n->prev = NULL;
// take care of empty list case
if (empty()) {
top = n;
end = n;
// take care of node belongs at beginning case
}
else if (getTop()->name > s) {
n->next = getTop();
n->prev = NULL;
setTop(n);
node *temp;
temp = n->next;
temp->prev = n;
// take care of inorder and end insert
}
else {
// insert in order case
node *curr = getTop(), *prev = curr;
while (curr != NULL) {
if (curr->name > s)break;
prev = curr;
curr = curr->next;
}
if (curr != NULL) { // search found insert point
n->next = curr;
cout << n->name << " " << n << " prev " << prev << " " << prev->name << endl;
n->prev = prev;
prev->next = n;
cout << "n->prev is: " << n->prev << " " << n->prev->name << endl;
cout << "n->next is: " << n->next << " " << n->next->name << endl;
}
// take care of end of list insertion
else if (curr == NULL) {// search did not find insert point
prev->next = n;
n->prev = prev;
cout << "n->prev is: " << n->prev << " " << n->prev->name << endl;
setEnd(n);
}
}
}
ostream& operator << (ostream& os, const linkedList& ll) {
//linkedList x = ll; // put this in and the code blows up - why?
node *n = ll.top;
if (n == NULL)cout << "List is empty." << endl;
else
while (n != NULL) {
os << n->name << endl;
os << n << endl;
if (n->next != NULL) {
os << "next is " << n->next << endl;
}
n = n->next;
}
return os;
}
void linkedList::reversePrint() {
node *n = end;
if (n == NULL)cout << "List is empty." << endl;
else
while (n != NULL) {
//cout << n->name << endl;
cout << "memory address of " << n->name << " is " << n << endl;
if (n->prev != NULL) {
cout << "prev is " << n->prev << endl;
}
n = n->prev;
}
return;
}
// return memory to heap
linkedList::~linkedList() {
cout << "~linkedList called." << endl;
node *curr = getTop(), *del;
while (curr != NULL) {
del = curr;
curr = curr->next;
delete(del);
}
}
int linkedList::menu() {
int choice = 0;
while (choice < 1 || choice > 5) {
cout << "\nEnter your choice" << endl;
cout << " 1. Add a name." << endl;
cout << " 2. Delete a name." << endl;
cout << " 3. Show list." << endl;
cout << " 4. Show reverse list. " << endl;
cout << " 5. EXIT " << endl;
cin >> choice;
}
return choice;
}
You are not setting the prev of the current in insertion into middle, just do:
n->next = curr;
curr->prev = n; // <-- this

Seg Fault 11 when creating NodeQueues

void NodeQueue::push(const DataType & value){
m_back = m_back->m_next = new Node(value, NULL); }
Hello, I am working with Node Queues and I am getting a seg fault 11 which I have narrowed down to my push function. I have been tweaking it for a while and cannot figure out what is wrong. Any suggestions?
This is the driver class:
NodeQueue nQueue;
cout << "Default Constructor: " << nQueue << endl;
DataType nParameter(1, 0);
NodeQueue nparameter(6, nParameter);
cout << "Paramaterized Constructor: " << nparameter << endl;
NodeQueue nCopier(nparameter);
cout << "Copy Constructor: " << nCopier << endl;
nCopier.pop();
cout << "Pop Function: " << nCopier << endl;
DataType nPushable(2,1);
nCopier.push(nPushable);
cout << "Push Function: " << nCopier << endl;
nQueue = nCopier;
cout << "Assignment Operator: " << nQueue << endl;
NodeQueue constructors below:
NodeQueue::NodeQueue() {
m_front = NULL;
m_back = NULL;
}
NodeQueue::NodeQueue(size_t size, const DataType & value) {
if(size <= 0) {
m_front = NULL;
} else {
m_front = new Node(value, NULL);
Node *temp = m_front;
for(size_t i = 0; i < (size); i++) {
temp->m_next = new Node(value, NULL);
temp = temp->m_next;
}
temp->m_next = NULL;
}
}
NodeQueue::NodeQueue(const NodeQueue & other) {
if(other.m_front != NULL) {
m_front = new Node(other.m_front->data(), NULL);
Node *newN = m_front;
Node *tempN = other.m_front;
while(tempN->m_next != NULL) {
tempN = tempN->m_next;
newN->m_next = new Node(tempN->data(), NULL);
newN = newN->m_next;
}
newN->m_next = NULL;
} else {
m_front = NULL;
}
}

How to delete a node in a linked list?

This is what I have so far, but it's not working. Basically skips to else if(cnode == preposition).
void LinkedList::Delete(Node *PrePosition) {
Node *cnode = head;
Node *pnode = NULL;
while (cnode != NULL) {
if (cnode->value != NULL) {
if (pnode == NULL) {
// if there is not previous node
head = cnode->next;
}
else if (cnode == PrePosition) {
// if there is previous node
cout << endl << "Deleting: " << cnode << endl;
pnode->next = cnode->next;
}
}
else {
// don't delete
pnode = cnode;
}
cnode = cnode->next;
}
}
1: Take the pointer from the previous node and point it to the next one after the one you want to delete
2: Delete the pointer from the previous node to the current node
3: Delete the pointer from the next node to the current node (if it is a doubly-linked list)
Three cases of delete in a singly linked-list:
delete the first node
void delete_first()
{
node *temp=new node;
temp=head;
head=head->next;
delete temp;
}
delete the last node
void delete_last()
{
node *current = new node;
node *previous = new node;
current=head;
while(current->next != NULL)
{
previous = current;
current = current->next;
}
tail = previous; // if you have a Node* tail member in your LinkedList
previous->next = NULL;
delete current;
}
delete at a particular position (your case)
void LinkedList::delete_position(int pos)
{
node *current=new node;
node *previous=new node;
current=head;
for(int i=1; i < pos; i++) //or i = 0; i < pos-1
{
previous=current;
current=current->next;
}
previous->next=current->next;
delete current;
}
^^ from codementor ^^
However if your function signature intends delete_node(Node* nodeToDelete) [PrePosition is not a good name in this case] and you want delete the node passed to the function without knowing its position in the list we can modify delete_position() like so:
void LinkedList::delete_node(Node* nodeToDelete)
{
node *current= head;
node *previous= nullptr;
if (head == nodeToDelete){
head = nodeToDelete->next;
delete nodeToDelete;
return
}//else
while(current != nodeToDelete)
{
previous = current;
current = current->next
}
previous->next = current->next;
delete nodeToDelete;
}
Also in your original code, if it's skipping the line you mentioned, pnode is always null when cnode has a non-null value in it.
Here are the full code
class SportShoe {
private:
struct nodeSport {
int ShoeID;
char BrandShoe[SIZE];
char TypeShoe[SIZE];
char ColourShoe[SIZE];
int SizeShoe;
float PriceShoe;
nodeSport *last;
};
nodeSport *first = NULL;
public:
int MenuSportShoe();
void AddSportShoe();
void DisplaySportShoe();
void DeleteSportShoe();
static void ExitSportShoe();
};
int SportShoe::MenuSportShoe() {
int OptionSportShoe = 0;
cout << endl;
cout << "Please select from the menu:" << endl;
cout << ":: 1 :: Add item to shoe list" << endl;
cout << ":: 2 :: Display shoes list" << endl;
cout << ":: 3 :: Delete item from the list" << endl;
cout << ":: 4 :: Back" << endl;
cout << "=>> ";
cin >> OptionSportShoe;
while (OptionSportShoe == 1){
AddSportShoe();
}
while (OptionSportShoe == 2){
DisplaySportShoe();
}
while (OptionSportShoe == 3){
DeleteSportShoe();
}
while (OptionSportShoe == 4){
ExitSportShoe();
}
return 0;
}
void SportShoe::AddSportShoe() {
nodeSport *tempShoe1, *tempShoe2;
tempShoe1 = new nodeSport;
cout << "Please enter the Shoe ID : (eg. 43210) " << endl;
cout << "=>> ";
cin >> tempShoe1->ShoeID;
cout << "Please enter the Shoe Brand: (eg. Adidas) " << endl;
cout << "=>> ";
cin.sync();
cin.getline(tempShoe1->BrandShoe,SIZE);
cout << "Please enter the Shoe Type : (eg. Running) " << endl;
cout << "=>> ";
cin.sync();
cin.getline(tempShoe1->TypeShoe,SIZE);
cout << "What is the Shoe Colour : (eg. Grey) " << endl;
cout << "=>> ";
cin.sync();
cin.getline(tempShoe1->ColourShoe,SIZE);
cout << "Please enter Shoe Size : (eg. 9) " << endl;
cout << "=>> ";
cin >> tempShoe1->SizeShoe;
cout << "Please enter the price of the Shoe : (eg. RM123.45) " << endl;
cout << "=>> RM ";
cin >> tempShoe1->PriceShoe;
tempShoe1->last = NULL;
if (first == NULL)
first = tempShoe1;
else
{
tempShoe2 = first;
while (tempShoe2->last != NULL)
tempShoe2 = tempShoe2->last;
tempShoe2->last = tempShoe1;
}
system("PAUSE");
MenuSportShoe();
}
void SportShoe::DisplaySportShoe() {
nodeSport *tempShoe1;
tempShoe1 = first;
while(tempShoe1){
cout << "ID : " << tempShoe1->ShoeID << endl;
cout << "Brand : " << tempShoe1->BrandShoe << endl;
cout << "Type : " << tempShoe1->TypeShoe << endl;
cout << "Colour : " << tempShoe1->ColourShoe << endl;
cout << "Size : " << tempShoe1->SizeShoe << endl;
cout << "Price : " << tempShoe1->PriceShoe << endl;
cout << endl;
tempShoe1 = tempShoe1->last;
}
system("PAUSE");
MenuSportShoe();
}
void SportShoe::DeleteSportShoe(){
nodeSport *tempShoe1, *tempShoe2;
int DataShoe;
tempShoe2 = tempShoe1 = first;
if(tempShoe1 == NULL)
{
cout << "\nList is empty!" << endl;
system("PAUSE");
MenuSportShoe();
}
while(tempShoe1 != NULL)
{
cout << "\nEnter the Shoes ID to be deleted: (eg. 123) ";
cin >> DataShoe;
tempShoe2 = tempShoe1;
tempShoe1 = tempShoe1->last;
if(DataShoe == tempShoe1-> ShoeID){
if(tempShoe1 == first) {
first = first->last;
cout << "\nData deleted ";
}
else{
tempShoe2->last = tempShoe1->last;
if(tempShoe1->last == NULL){
tempShoe2 = tempShoe2;
}
cout << "\nData deleted ";
}
delete(tempShoe1);
system("PAUSE");
MenuSportShoe();
}
else{
cout << "\nRecord not Found!!!" << endl;
system("PAUSE");
MenuSportShoe();
}
}
}
void SportShoe::ExitSportShoe(){
int sepatu;
cout << endl;
cout << "Please choose the option below."<<endl;
cout << ":: 1 :: Sport Shoe." << endl;
cout << ":: 2 :: Ladies High Heel." << endl;
cout << ":: 3 :: Exit" << endl;
cout << "=>> ";
cin >> sepatu;
while(sepatu == 1){
SportShoe listShoe;
listShoe.MenuSportShoe();
}
while(sepatu == 2){
HighHeel listShoe;
listShoe.MenuHighHeel();
}
while(sepatu == 3){
cout << "Thank you. Till we meet again."<< endl;
exit(1);
}
}
main() {
cout << "Hello! Welcome to MySepatu Online Shop administrator."<< endl;
cout << endl;
SportShoe::ExitSportShoe();
HighHeel::ExitHighHeel();
return 0;
}
public class linkedList {
int count = 0;
class Node {
int element;
Node next;
Node(int element) {
this.element = element;
}
}
Node head = null;
Node tail = null;
public void addNode(int Object) {
Node newNode = new Node(Object);
if (head == null) {
head = tail = newNode;
} else {
tail.next = newNode;
tail = newNode;
}
}
public void Display() {
Node current = head;
while (current!=null) {
System.out.println(current.element);
count ++;
current = current.next;
}
}
public void Length() {
System.out.println(count);
}
public void Remove(int node) {
Node curr = head;
while (curr!=null) { // looping the nodes
if (curr.element == node ) {
curr.element = curr.next.element;
curr = curr.next;
// To fix the Duplicates
while (curr!= tail) {
curr.element = curr.next.element;
curr = curr.next;
}
RemoveEnd();
break;
}
curr = curr.next;
}
}
public void RemoveEnd() {
Node current3 = head;
while (current3.next != tail) {
current3 = current3.next;
}
tail = current3;
tail.next = null;
}
}

Can't read string from struct when using C++ std::stack::push function

I wrote this testing code for my 8 puzzle project. The problem is the line23 string currentPath can't read anything from the Node. The message for debug is "Cannot evaluate function -- may be inlined". As the result the function cant go through the switch loop.
I dont similar project before, they all work well. Any one know what is the problem?
In the Line 3 of the screen, it suppose to print the string variable "currentPath", but right now it's nothing. As the result the error statement pop out.
#include
#include
#include
#include // string::size_type
#include // std::swap
using namespace std;
struct Node{
string state;
string path;
int depth;
};
Node dequeue;
stack<Node> enqueue;
stack<Node> visitedList;
void AddNextPath(Node *&listpointer){
Node *temp, *newNode;
temp = listpointer;
newNode = new Node;
string currentPath = listpointer->path;
cout << currentPath << endl;
if(currentPath.length() == 9){
string::size_type location = currentPath.find("0"); // Finde char index of '0' in the string
char tempCharArray[9];
strcpy(tempCharArray, currentPath.c_str()); // Convert the string to char array
string newState;
// The required order for traverse each state is U,R,D,L.
// When add new node to stack, this order has to done in reverse order: L,D,R,U
switch (location){
// Each case represents a location of 3x3 graphic map
case 0:
// Move down
swap(tempCharArray[0],tempCharArray[3]);
newState = tempCharArray;
newNode->state = newState;
newNode->path = temp->path.append("D");
newNode->depth = temp->depth + 1;
enqueue.push(*newNode);
// Move right
swap(tempCharArray[0],tempCharArray[1]);
newState = tempCharArray;
newNode->state = newState;
newNode->path = temp->path.append("R");
newNode->depth = temp->depth + 1;
enqueue.push(*newNode);
break;
// case 1:
}
}
else{
cout << "The length of the current state is " << currentPath.length() << endl;
cout << "Warning: state length error!\r\nExit." << endl;
exit(0);
}
}
int main()
{
Node *testNode = new Node;
testNode->depth = 0;
testNode->state = "087654321";
testNode->path = "";
cout << "The current state is " << testNode->state << endl;
cout << "The path is " << testNode->path << endl;
enqueue.push(*testNode);
AddNextPath(testNode);
cout << "The size of enqueue is" << enqueue.size() << endl;
Node topNode;
topNode = enqueue.top();
cout << "The top state is " << topNode.state << endl;
cout << "The path is " << topNode.path << endl;
cout << "The depth is " << topNode.depth << endl;
return 0;
}
#include <stack>
#include <iostream>
using namespace std;
struct Node{
string state;
string path;
int depth;
};
Node dequeue;
stack<Node> enqueue;
stack<Node> visitedList;
void AddNextPath(Node *&listpointer){
Node *temp, *newNode;
temp = listpointer;
newNode = new Node;
string currentPath = listpointer->path;
cout << currentPath.c_str() << endl;
if(currentPath.length() == 9){
string::size_type location = currentPath.find("0"); // Finde char index of '0' in the string
char tempCharArray[10];
strcpy(tempCharArray, currentPath.c_str()); // Convert the string to char array
string newState;
// The required order for traverse each state is U,R,D,L.
// When add new node to stack, this order has to done in reverse order: L,D,R,U
switch (location){
// Each case represents a location of 3x3 graphic map
case 0:
// Move down
swap(tempCharArray[0],tempCharArray[3]);
newState = tempCharArray;
newNode->state = newState;
newNode->path = temp->path.append("D");
newNode->depth = temp->depth + 1;
enqueue.push(*newNode);
// Move right
swap(tempCharArray[0],tempCharArray[1]);
newState = tempCharArray;
newNode->state = newState;
newNode->path = temp->path.append("R");
newNode->depth = temp->depth + 1;
enqueue.push(*newNode);
break;
// case 1:
}
}
else{
cout << "The length of the current state is " << currentPath.length() << endl;
cout << "Warning: state length error!\r\nExit." << endl;
exit(0);
}
}
int main()
{
Node *testNode = new Node;
testNode->depth = 0;
testNode->state = "087654321";
testNode->path = "0dddddddd";
cout << "The current state is " << testNode->state.c_str() << endl;
cout << "The path is " << (testNode->path).c_str() << endl;
enqueue.push(*testNode);
AddNextPath(testNode);
cout << "The size of enqueue is" << enqueue.size() << endl;
Node topNode;
topNode = enqueue.top();
cout << "The top state is " << topNode.state.c_str() << endl;
cout << "The path is " << topNode.path.c_str() << endl;
cout << "The depth is " << topNode.depth << endl;
return 0;
}
I fixed three things.
.c_str()
char tempCharArray[9]; -> char tempCharArray[10];
testNode->path = "0dddddddd";
I might misunderstand your question. but that code is working.