strdup for converting const char* to char* - c++

I have designed for Huffman tree convert binary code with shorter bin code. In main if you call a Binary tree.init(q), then the tree would come out with key: frequency and value: bin code. The problem is converting const char* with char*. I've looked at some codes, and here I converted it by using strdup. Sometimes works fine but sometimes doesn't work. so I checked out the parameter for the function. Is there wrong in calling strdup or maybe others?
#pragma once
#include <stdio.h>
#include <queue>
#include <iostream>
#include "pch.h"
#include <string.h>
#include <string>
#define _CRT_SECURE_NO_WARNINGS
//this is a header file
using namespace std;
class Node
{
public:
//key : frequency, value : code
int f;
char* code;
Node* left;
Node* right;
int getFrequency()
{
return f;
}
char* getCode()
{
return code;
}
void init(int frequency, char* codestring)
{
f = frequency;
code = codestring;
}
Node* getLeft() {
return left;
}
Node* getRight()
{
return right;
}
void setLeft(Node* L)
{
left = L;
}
void setRight(Node* R)
{
right = R;
}
void setFrequency(int frequency)
{
f = frequency;
}
void setCode(char* string)
{
code = string;
}
};
class BinaryTree
{
public:
typedef priority_queue<int, vector<int>, greater<int>> pq;
pq q;
Node* proot;
int sizeofqueue;
void init(pq PriorityQueue)
{
q = PriorityQueue;
sizeofqueue = q.size();
N = 0;
int comparetimes = q.size() - 1;
for (int i = 0; i < comparetimes; i++)
{
if (i == 0)
{
put_first_two_nodes();
}
else
{
if (proot->getFrequency() <= q.top())
{
put_right_node();
}
else if (proot->getFrequency() > q.top())
{
put_left_node();
}
q.pop();
}
}
}
void put_first_two_nodes()
{
Node* pleft = new Node();
(*pleft).setFrequency(q.top());
(*pleft).setCode("0");
q.pop();
Node* pright = new Node();
(*pright).setFrequency(q.top());
(*pright).setCode("1");
put(pleft, pright);
q.pop();
}
void put_right_node()
{
Node* pright = new Node();
pright->setFrequency(q.top());
pright->setCode("1");
put(proot, pright);
appendcode(0);
}
void appendcode(int prefix)
{
string pre;
if (prefix == 1) pre = "1";
else pre = "0";
Node* targetNode = proot->getRight();
char* rcode = targetNode->getRight()->getCode();
char* lcode = targetNode->getLeft()->getCode();
string lefts = pre;
string rights = pre;
lefts.append(lcode);
rights.append(rcode);
char* leftstring = strdup(lefts.c_str());
char* rightstring = strdup(rights.c_str());
targetNode->getLeft()->setCode(leftstring);
targetNode->getRight()->setCode(rightstring);
free(leftstring);
free(rightstring);
}
void put_left_node()
{
Node* pleft = new Node();
pleft->setFrequency(q.top());
pleft->setCode("0");
put(pleft, proot);
appendcode(1);
}
char* get(int k)
{
return getItem(*proot, k);
}
char* getItem(Node root, int k)
{
//if there's no node
if (&root == nullptr) return "";
//if f or root > k, search left sibling
if (root.getFrequency() > k) return getItem(*(root.getLeft()), k);
//else, search right sibling
else if (root.getFrequency() < k) return getItem(*(root.getRight()), k);
//get it
else return root.getCode();
}
void put(Node* left, Node* right)
{
put_item(left,right);
}
void put_item(Node* left, Node* right)
{
//make new node that has sibling with left and right
Node* newnode = new Node();
newnode->setLeft(left);
newnode->setRight(right);
//exchange the new node and root without losing data
Node* temp;
temp = proot;
proot = newnode;
newnode = temp;
//proot's frequency : left f + right f
(*proot).setFrequency((*left).getFrequency() + (*right).getFrequency());
}
void printpost()
{
postorder(proot);
}
void postorder(Node* root)
{
if (root != nullptr)
{
if (root->getLeft() != nullptr) postorder(root->getLeft());
if (root->getRight() != nullptr) postorder(root->getRight());
printf("%d : %s ",root->getFrequency(), root->getCode());
}
}
private:
int N;
Node root;
};

You shouldn't use const char* and char* at all in c++ (unless when sometimes dealing with legacy or foreign interfaces).
Switch up your code to use eg. std::string or std::string_view (c++17) instead (string_view requires a bit more understanding to handle correctly and is const so to speak - so I would stick to string off the bat). Pass std::string by reference or by const reference where neccesary. The overhead of std::string is for most programs negliable.

Related

C++ reach class/structure field

I'm challenging myself to create my own custom integer array by making a class and structure with some functions. When I run the program I don't get an error, but the data of the index isn't being set, and I don't understand why.
Array class file
#include "IntArray.hpp"
using namespace std;
struct IntArrayIndex {
public:
IntArrayIndex* next = NULL;
int data;
IntArrayIndex(int Data) {
this->data = Data;
}
IntArrayIndex() {
this->data = 0;
}
};
class IntArray {
public:
IntArrayIndex head = *(new IntArrayIndex());
int length;
IntArray() {
this->length = 1;
this->head = *(new IntArrayIndex());
}
int getIndex(int index) {
if (index >= length) {
throw invalid_argument("Index out of range. Returned -1");
}
IntArrayIndex current = head;
if (index > 0) {
current = *current.next;
getIndex(--index);
}
return current.data;
}
void setIndex(int index, int data) {
IntArrayIndex current = head;
if (index > 0) {
if (current.next == NULL) {
current.next = new IntArrayIndex();
length++;
}
current = *current.next;
setIndex(--index, data);
}
current.data = data;
}
};
Main file
#include <iostream>
#include "IntArray.cpp"
int main(int argc, const char * argv[]) {
IntArray* l = new IntArray();
l->setIndex(0, 1);
std::cout << l->getIndex(0);
}
OUTPUT:
0
Program ended with exit code: 0
Changing the pointers in setIndex ended up fixing the problem:
void setIndex(int index, int data) {
IntArrayIndex* current = &head;
if (index > 0) {
if (current->next == NULL) {
current->next = new IntArrayIndex();
length++;
}
current = current->next;
setIndex(--index, data);
}
current->data = data;
}

TRIE data structure implementation in c++

I have written a simple code to implement a trie data structure in c++. But when I run this program, it gives segmentation error as an output.
Kindly please correct me, where i have been wrong.
#include <bits/stdc++.h>
using namespace std;
struct trienode {
struct trienode * child[26];
bool isEnd;
trienode()
{
isEnd = false;
for(int i = 0; i < 26; i++)
{
child[i] = NULL;
}
}
};
struct trienode * root;
void insert_str(string &s, int n)
{
trienode * curr = root;
int i;
for(i = 0; i < n; i++)
{
int index = s[i] - 'a';
if(curr -> child[index] == NULL)
{
curr -> child[index] = new trienode();
}
else
{
curr = curr -> child[index];
}
}
curr -> isEnd = true;
}
int main()
{
string s1 = "yash";
insert_str(s1, 4);
}
You haven't allocated any memory for your root node.
Normally you would have a separate class to handle the trie as a whole. It can then allocate the root node.
class trie
{
public:
trie()
{
root = new trienode();
}
void insert_str(string &s, int n)
{
...
}
private:
trienode* root;
};
int main()
{
trie t;
string s1 = "yash";
t.insert_str(s1, 4);
}

C++ Binary Tree Programming new Nodes leaving Scope issue

I am a java programmer teaching myself C++.
While writing a binary tree I found that my program did not "add" values to the tree.
#include "stdafx.h"
#include <cstdlib>
#include <iostream>
using namespace std;
class BinaryTree {
struct Node {
public:
int val;
Node* left;
Node* right;
Node::Node(int v) {
val = v;
left = nullptr;
right = nullptr;
}
};
public:
BinaryTree() {
root = nullptr;
}
int size = 0;
int length();
bool BinaryTree::add(int v);
void printTree();
private:
void printTree(Node* n);
Node* root;
};
bool BinaryTree::add(int v) {
if (root == nullptr) {
root = new Node(v);
++size;
return true;
}
Node* ref = root;
cout << ref->val;
while (ref != nullptr) {
if (v < ref->val) {
ref = ref->left;
}
else if (v > ref->val) {
ref = ref->right;
}
else if (v == ref->val) {
return false;
}
}
Node *newNode = new Node(v);
ref = newNode;
++size;
return true;
}
void BinaryTree::printTree() {
printTree(root);
}
void BinaryTree::printTree(Node* n) {
if (n == nullptr) {
return;
}
printTree(n->left);
cout << n->val << endl;
printTree(n->right);
}
int BinaryTree::length() {
return size;
}
void main(int i) {
BinaryTree tree = BinaryTree();
tree.add(6);
tree.add(3);
tree.add(5);
tree.add(7);
tree.add(1);
tree.add(0);
tree.add(0);
tree.printTree();
cout << "binary tree sz is " << tree.length() << endl;
while (true) {};
}
I have been unable to find the problem in regards to why the tree doesn't commit new Nodes except the root.
I used "new" in the code when writing (ref = new Node) etc in the adds method because this should prevent the new Node from being destroyed once it leaves the scope.
If anyone can enlighten me on this issue I will be greatly thankful.
To add a node to the tree you have to link it to some existing node, as in
existing_node->{left or right} = new_node;
Once ref becomes nullptr, you don't have a valid existing node anymore, and it is too late to do anything. Instead, traverse the tree as long as ref->{left or right} is valid:
if (v < ref->val) {
if (ref->left) {
ref = ref->left;
} else {
ref->left = newNode;
return true;
}
}
// etc for v > ref->val

How to fix Access Violation Reading location error? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am currently working on a program that uses a Hash table. I have worked on my own Hash table class and the program works but then crashes after it has already done the work involving the hash table. The error I get is a Access Violation reading location error. I have spent hours going through my code and still cannot find what I'm doing wrong or why the program is crashing. Here are my problem classes below:
Hashtable.h:
#ifndef HASHTABLE_H
#define HASHTABLE_H
#include <string>
#include "LinkedList.h"
#include <iostream>
using namespace std;
class hashTable
{
public:
hashTable();
virtual ~hashTable();
void insertNode(string nodeData);
bool removeNode(string nodeKey);
Node * checkForDuplicate( string nodeData );
private:
LinkedList * tableArray;
int length;
int hash(string stateKey);
};
#endif // HASHTABLE_H
Hashtable.cpp:
#include "hashTable.h"
hashTable::hashTable()
{
length = 181667;
tableArray = new LinkedList[length];
}
int hashTable::hash(string stateKey) {
int multiplier = 1;
int total = 0;
int l = stateKey.length();
for(int i = l - 1; i > -1; --i) {
int temp;
temp = (stateKey[i] - '0') * multiplier;
total += temp;
multiplier = multiplier * 10;
}
return(total) % length;
}
void hashTable::insertNode(string stateData) {
Node * newNode;
newNode = new Node;
newNode->data = stateData;
int index = hash(newNode -> data);
tableArray[index].insertNode(newNode);
delete newNode;
}
bool hashTable::removeNode(string nodeKey) {
int index = hash(nodeKey);
return tableArray[index].removeNode(nodeKey);
}
Node * hashTable::checkForDuplicate( string nodeData )
{
int index = hash( nodeData );
return tableArray[ index ].getNode(nodeData);
}
hashTable::~hashTable()
{
delete [] tableArray;
//dtor
}
LinkedList.h:
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include<string>
#include<iostream>
using namespace std;
struct Node {
string data;
Node *next;
};
class LinkedList
{
public:
LinkedList();
void insertNode(Node * newNode);
bool removeNode(string stateData);
Node * getNode(string stateData);
int getLength();
virtual ~LinkedList();
private:
Node * top;
int length;
};
#endif // LINKEDLIST_H
LinkedList.cpp:
#include "LinkedList.h"
LinkedList::LinkedList()
{
top = new Node;
top->next = NULL;
length = 0;
}
void LinkedList :: insertNode(Node * newNode) {
Node * a = top;
Node * b = top;
while(b) {
a = b;
b = a -> next;
if (a== NULL) { break; }
}
a -> next = newNode;
newNode -> next = NULL;
length++;
}
bool LinkedList :: removeNode(string stateData) {
if(!top -> next){
return false;
}
Node * a = top;
Node * b = top;
while(b) {
if(b->data == stateData) {
a->next = b->next;
delete b;
length--;
return true;
}
a = b;
b = a ->next;
}
return false;
}
Node * LinkedList :: getNode(string stateData) {
if(top == NULL) { return NULL ;}
Node * current = top;
while (current->next != NULL) {
if((current->data == stateData)) {
return current;
}
current = current -> next;
}
return NULL;
}
int LinkedList :: getLength() {
return length;
}
LinkedList::~LinkedList()
{
Node * a = top;
Node * b = top;
while (b) {
a = b;
b = a->next;
if(b) delete a;
}
}
Your hashTable::insertNode() method is allocating a new Node object, then passing it to LinkedList::insertNode() to take ownership of the object, but then delete's it afterwards, thus leaving the LinkedList with a dangling pointer to invalid memory. Any access to that node will cause undefined behavior. DO NOT delete the new node after LinkedList takes ownership of it.
It would be better if LinkedList::insertNode() took a string as input instead of a Node* pointer. Let LinkedList allocate the new node internally.
Also, there are some other minor issues with your LinkedList() implementation in general (like not following the Rule of Three, and not using a double-linked list for more efficient inserts and removals).
Try something more like this instead:
Hashtable.h:
#ifndef HASHTABLE_H
#define HASHTABLE_H
#include <string>
#include "LinkedList.h"
class hashTable
{
public:
hashTable();
hashTable(const hashTable &src);
~hashTable();
void insertNode(const std::string &nodeData);
bool removeNode(const std::string &nodeData);
bool checkForDuplicate(const std::string &nodeData);
hashTable& operator=(const hashTable &rhs);
private:
std::vector<LinkedList> tableArray;
int length;
int hash(const std::string &nodeData);
};
#endif // HASHTABLE_H
Hashtable.cpp:
#include "hashTable.h"
hashTable::hashTable()
: length(181667), tableArray(new LinkedList[length])
{
}
hashTable::hashTable(const hashTable &src)
: length(src.length), tableArray(new LinkedList[length])
{
for (int i = 0; i < length; ++i)
tableArray[i] = src.tableArray[i];
}
hashTable::~hashTable()
{
delete[] tableArray;
}
hashTable& hashTable::operator=(const hashTable &rhs)
{
hashTable tmp(rhs);
std::swap(tableArray, tmp.tableArray);
std::swap(length, tmp.length);
return *this;
}
int hashTable::hash(const std::string &nodeData)
{
int multiplier = 1;
int total = 0;
int l = nodeData.length();
for(int i = l - 1; i > -1; --i)
{
int temp = (nodeData[i] - '0') * multiplier;
total += temp;
multiplier *= 10;
}
return total % length;
}
void hashTable::insertNode(const std::string &nodeData)
{
int index = hash(nodeData);
tableArray[index].insertNode(nodeData);
}
bool hashTable::removeNode(const std::string &nodeData)
{
int index = hash(nodeData);
return tableArray[index].removeNode(nodeData);
}
bool hashTable::checkForDuplicate(const std::string &nodeData)
{
int index = hash(nodeData);
return (tableArray[index].getNode(nodeData) != NULL);
}
LinkedList.h:
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include <string>
struct Node
{
std::string data;
Node *previous;
Node *next;
};
class LinkedList
{
public:
LinkedList();
LinkedList(const LinkedList &src);
~LinkedList();
void insertNode(const std::string &nodeData);
bool removeNode(const std::string &nodeData);
Node* getNode(const std::string &nodeData);
int getLength();
LinkedList& operator=(const LinkedList &rhs);
private:
Node *head;
Node *tail;
int length;
};
#endif // LINKEDLIST_H
LinkedList.cpp:
#include "LinkedList.h"
#inclue <algorithm>
LinkedList::LinkedList()
: head(NULL), tail(NULL), length(0)
{
}
LinkedList::LinkedList(const LinkedList &src)
: head(NULL), tail(NULL), length(0)
{
Node *current = src.top;
while (current != NULL)
{
insertNode(current->data);
current = current->next;
}
}
LinkedList::~LinkedList()
{
Node *current = top;
while (current != NULL)
{
Node *next = current->next;
delete current;
current = next;
}
}
LinkedList& LinkedList::operator=(const LinkedList &rhs)
{
LinkedList tmp;
Node *current = rhs.top;
while (current != NULL)
{
tmp.insertNode(current->data);
current = current->next;
}
std::swap(top, tmp.top);
std::swap(bottom, tmp.bottom);
std::swap(length, tmp.length);
return *this;
}
void LinkedList::insertNode(const string &nodeData)
{
Node *newNode = new Node;
newNode->data = nodeData;
newNode->previous = NULL;
newNode->next = NULL;
if (top == NULL) top = newNode;
if (bottom != NULL)
{
newNode->previous = bottom;
bottom->next = newNode;
}
bottom = newNode;
length++;
}
bool LinkedList::removeNode(const string &nodeData)
{
Node* node = getNode(nodeData);
if (node != NULL)
{
if (node->next != NULL)
node->next->previous = node->previous;
if (node->previous != NULL)
node->previous->next = node->next;
if (top == node)
top = node->next;
if (bottom == node)
bottom = node->previous;
delete node;
length--;
return true;
}
return false;
}
Node* LinkedList::getNode(const string &nodeData)
{
Node *current = top;
while (current != NULL)
{
if (current->data == nodeData)
return current;
current = current->next;
}
return NULL;
}
int LinkedList::getLength()
{
return length;
}
With that said, you can then get rid of LinkedList altogether by using std::list instead, and simplify hashTable's memory management by using std::vector:
Hashtable.h:
#ifndef HASHTABLE_H
#define HASHTABLE_H
#include <string>
#include <list>
#include <vector>
class hashTable
{
public:
hashTable();
void insertNode(const std::string &nodeData);
bool removeNode(const std::string &nodeData);
bool checkForDuplicate(const std::string &nodeData);
private:
std::vector< std::list<std::string> > tableArray;
int hash(const std::string &stateKey);
};
#endif // HASHTABLE_H
Hashtable.cpp:
#include "hashTable.h"
#include <algorithm>
hashTable::hashTable()
: tableArray(181667)
{
}
int hashTable::hash(const std::string &nodeData)
{
int multiplier = 1;
int total = 0;
int l = nodeData.length();
for(int i = l - 1; i > -1; --i)
{
int temp = (nodeData[i] - '0') * multiplier;
total += temp;
multiplier *= 10;
}
return total % length;
}
void hashTable::insertNode(const std::string &nodeData)
{
int index = hash(nodeData);
tableArray[index].push_back(nodeData);
}
bool hashTable::removeNode(const string &nodeData)
{
int index = hash(nodeData);
std::list<std::string>::iterator iter = std::find(tableArray[index].begin(), tableArray[index].end(), nodeData);
if (iter != tableArray[index].end())
{
tableArray[index].erase(iter);
return true;
}
return false;
}
bool hashTable::checkForDuplicate(const std::string &nodeData)
{
int index = hash(nodeData);
std::list<std::string>::iterator iter = std::find(tableArray[index].begin(), tableArray[index].end(), nodeData);
return (iter != tableArray[index].end());
}

Node does not name a type error

I have searched through the other questions and none of them seem to apply
exactly.
I am writing a program that finds a route through a maze,
the only real thing im having a problem with is this one compiler error.
It has to do with the one function I have the returns a Node ( struct).
Header file: (I cut the define stuff off)
#include <iostream>
#include <string>
using namespace std;
class Graph {
private:
struct Node {
int id; //int id
Node * north; //north path node
Node * south; //south path node
Node * east; //east path node
Node * west; //went path node
bool visited; // visited bool
};
//this struct holds the path that is found.
struct Elem {
int id; //The id of the node
string last; //the door that it passed through
Elem * back; //back one path
Elem * next; //forward one path
};
//This is a graph with a very smart struct
//This is the main node that makes up the graph.
Node * start;
Node ** initArr;
int arrLen;
Elem * head;
Elem * tail;
int path;
public:
Graph();
//Constructs empty graph
Graph(const Graph &v);
//copy constructor
~Graph();
//destructor
Graph & operator = (const Graph &v);
//assignment operator
void output(ostream & s) const;
//Prints the graph
void input(istream & s);
//input and creates the graph
Node * find(int id);
//finds the node in the graph
void makePath();
//makes a path through the maze
bool findPath(Node* cur, string room);
//worker function for recursion
void pathOut(ostream & s) const;
//Outputs the found path
void removeTail();
//Removes the last element
void addTail(Node* n, string door);
//Adds the element to the tail
//Mutators
void setId(Node* n ,int x);
void setVisited(Node* n, bool v);
//Elem Mutator
void seteId(Elem* e, int x);
//Elem Accessor
int geteId(Elem* e);
//Accessors
int getId(Node* n);
bool getVisited(Node* n);
};
And my actual code file.
#include <iostream>
#include "graph.h"
using namespace std;
//Constructs empty graph
Graph::Graph()
{
start = 0;
head = tail = 0;
path = 0;
}
//copy constructor
Graph::Graph(const Graph &v)
{
//not implemented
}
//destructor
Graph::~Graph()
{
for(int i = 0; i < arrLen + 1; i++)
{
delete initArr[i];
}
while(head != 0)
{
Elem* p = head;
head = head->next;
delete p;
}
delete[] initArr;
}
//assignment operator
Graph & Graph::operator = (const Graph &v)
{
//not implemented
}
//Prints the graph
void Graph::output(ostream & s) const
{
s<<"Node"<<'\t'<<"North"<<'\t'<<"East"<<'\t'<<"South"<<'\t'<<"West"<<'\n';
for(int i = 1; i < arrLen + 1; i++)
{
Node* temp = initArr[i];
s<<temp->id<<'\t';
if(temp->north != 0)
s<<temp->north->id<<'\t';
else
s<<"--"<<'\n';
if(temp->east != 0)
s<<temp->east->id<<'\t';
else
s<<"--"<<'\n';
if(temp->south != 0)
s<<temp->south->id<<'\t';
else
s<<"--"<<'\n';
if(temp->west != 0)
s<<temp->west->id<<'\t';
else
s<<"--"<<'\n';
s<<'\n';
}
}
//input and creates the graph
void Graph::input(istream & s)
{
int length = 0;
s>>length;
arrLen = length;
if(s)
{
//define array
initArr = new Node*[length + 1];
int temp = 0;
for(int i = 1; i < length + 1; i++)
{
//Create node
s>>temp;
Node* n = new Node;
n->id = temp;
n->visited = false;
//Add to array
initArr[i] = n;
}
//Make Exit Node
Node *x = new Node;
x->id = 0;
x->visited = false;
initArr[0] = x;
//Loop through all of the node input
int tn = 0;
for(int f = 0; f < length; f++)
{
//Set Pointers
s>>tn;
Node* curNode = find(tn);
int n = 0;
int e = 0;
int st = 0;
int w = 0;
s>>n>>e>>st>>w;
curNode->north = find( n );
curNode->east = find( e );
curNode->south = find( st );
curNode->west = find( w );
}
//set Entry point to graph
int last = 0;
s>>last;
start = find(last);
}
}
//finds the node in the array
Node* Graph::find(int id)
{
if( id == 0)
{
return initArr[0];
}
if(id == -1)
{
return 0;
}
else
{
for(int i = 1; i < arrLen + 1; i++)
{
if(initArr[i]->id == id)
{
return initArr[i];
}
}
cerr<<"NOT FOUND IN GRAPH";
return 0;
}
}
//makes a path through the maze
void Graph::makePath()
{
if(findPath(start->north, "north") == true)
{
path = 1;
return;
}
else if( findPath(start->east, "east") == true)
{
path = 1;
return;
}
else if( findPath(start->south, "south") == true)
{
path = 1;
return;
}
else if( findPath(start->west, "west") == true)
{
path = 1;
return;
}
return;
}
//finds a path to the outside
bool Graph::findPath(Node* cur, string room)
{
addTail(cur, room);
if(cur = initArr[0])
{
return true;
}
if(cur->north != 0 && cur->north->visited == false)
{
cur->visited = true;
findPath(cur->north, "north");
}
else if(cur->east != 0 && cur->east->visited == false)
{
cur->visited = true;
findPath(cur->north, "east");
}
else if(cur->south !=0 && cur->south->visited == false)
{
cur->visited = true;
findPath(cur->north, "south");
}
else if(cur->west != 0 && cur->west->visited == false)
{
cur->visited = true;
findPath(cur->north, "west");
}
else
{
cur->visited = false;
removeTail();
}
}
//Outputs the found path
void Graph::pathOut(ostream & s) const
{
if(path == 1)
{
Elem *p;
p = head->next;
while(p != 0)
{
s<<p->id<<"--> "<<p->last;
p= p->next;
}
}
else if(path == 0)
{
}
}
//Removes the last element in the chain
void Graph::removeTail()
{
Elem* temp = 0;
temp = tail;
tail = tail->back;
delete temp;
}
//Adds the element to the tail
void Graph::addTail(Node* n, string door)
{
if(head != 0)
{
Elem* temp = new Elem;
temp->id = n->id;
tail->next = temp;
tail->last = door;
temp->back = tail;
temp->next = 0;
tail = 0;
}
else
{
Elem *p = new Elem;
p->last = "";
p->back = 0;
p->next = 0;
head = p;
tail = p;
}
}
//Mutators
void Graph::setId(Node *n ,int x)
{
n->id = x;
}
void Graph::setVisited(Node *n, bool v)
{
n->visited = v;
}
//Elem Mutator
void Graph::seteId(Elem *e, int x)
{
e->id = x;
}
//Elem Accessor
int Graph::geteId(Elem *e)
{
return e->id;
}
//Accessors
int Graph::getId(Node *n)
{
return n-> id;
}
bool Graph::getVisited(Node *n)
{
return n->visited;
}
/*
//This is a graph with a very smart struct
//This is the main node that makes up the graph.
struct Node {
int id; //int id
Node *north; //north path node
Node *south; //south path node
Node *east; //east path node
Node *west; //went path node
bool visited; // visited bool
};
//this struct holds the path that is found.
struct Elem {
int id; //The id of the node
string last; //the door that it passed through
Elem* back; //back one path
Elem* next; //forward one path
};
Node* Start;
Node ** initArr;
Elem* head;
Elem* tail;
*/
//outputs using named operation
ostream & operator << (ostream &s, const Graph & v)
{
v.output(s);
return s;
}
The error is occurring on the find function.
In the cpp file, Node is not in global scope. It's nested inside Graph as such, you need to qualify it in a return type:
Graph::Node* Graph::find(int id){
// ...
}
Inside the function, you're in the scope of Graph again, as such you do not need to qualify it.
You have both Node and Element defined as structs inside the class Graph. It would be better to define them outside the class Graph. You can define a separate Node class and store the element struct as its private members. The error happens because Node is a private member of Graph, which can be accessed as Graph::Node. E.g. Graph::Node* find(...).