C++ reach class/structure field - c++

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;
}

Related

strdup for converting const char* to char*

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.

Implementation of Queue in C++

When I study the DataStructrue in my school, I implemented the Queue.
School's DataStructure class process is below.
student implemnted the DS
student submit in Domjudge
Domjudge score the code based by test cases.
My freind implemented the Queue like below.
#include <iostream>
#include <string>
using namespace std;
class Node {
public:
int data;
Node* next;
Node() {}
Node(int e) {
this->data = e;
this->next = NULL;
}
~Node(){}
};
class SLinkedList {
public:
Node* head;
Node* tail;
SLinkedList() {
head = NULL;
tail = NULL;
}
void addFront(int X) {
Node* v = new Node(X); // new Node
if (head == NULL) {
// list is empty
head = tail = v;
}else {
v->next = head;
head = v;
}
}
int removeFront() {
if (head == NULL) {
return -1;
}else{
Node* tmp = head;
int result = head->data;
head = head->next;
delete tmp;
return result;
}
}
int front() {
if (head == NULL) {
return -1;
}else {
return head->data;
}
}
int rear() {
if (head == NULL) {
return -1;
}else {
return tail->data;
}
}
int empty() {
if (head == NULL) {
return 1;
}else {
return 0;
}
}
void addBack(int X) {
Node* v = new Node(X);
if (head == NULL) {
head = tail = v;
}else {
tail->next = v;
tail = v;
}
}
~SLinkedList() {}
};
class LinkedQ {
public:
int n = 0;
int capacity;
Node* f;
Node* r;
SLinkedList Q;
LinkedQ(int size) {
capacity = size;
f = NULL;
r = NULL;
}
bool isEmpty() {
return n == 0;
}
int size() {
return n;
}
int front() {
return Q.front();
}
int rear() {
return Q.rear();
}
void enqueue(int data) {
if (n == capacity) {
cout << "Full\n";
}else {
Q.addBack(data);
n++;
}
}
};
int main() {
int s, n;
string cmd;
cin >> s >> n;
listQueue q(s);
for (int i = 0; i < n; i++) {
cin >> cmd;
if (cmd == "enqueue") {
int x;
cin >> x;
q.enqueue(x);
}else if (cmd == "size") {
cout << q.size() << "\n";
}else if (cmd == "isEmpty") {
cout << q.isEmpty() << "\n";
}else if (cmd == "front") {
q.front();
}else if (cmd == "rear") {
q.rear();
}
}
}
And I implmented like this (Node class and main are same, So I pass the code)
#include <iostream>
#include <string>
using namespace std;
class Node{...};
class listQueue {
public:
Node* head;
Node* tail;
int capacity;
int n = 0;
listQueue() {
head = NULL;
tail = NULL;
}
void enqueue(int X) {
Node* v = new Node(X); // new Node
if (n==capacity) {
cout << "Full\n";
return;
}
if (head == NULL) {
// Queue is empty
head = tail = v;
}else {
v->next = head;
head = v;
}
}
int front() {
if (head == NULL) {
return -1;
}else {
return head->data;
}
}
int rear() {
if (head == NULL) {
return -1;
}else {
return tail->data;
}
}
int empty() {
if (head == NULL) {
return 1;
}else {
return 0;
}
}
~listQueue() {}
};
test cases are just enqueue
but my friend is correct, and my code has occured memory over error.
So I check the usage of memory in Domjudge, My friend code and My code has very big gap in memory usage.
Why these two codes have memory usage gap big?
P.S I can't speak English well. If there is something you don't understand, please tell me.
First, rear is incorrect. It checks head and return tail. It happens to correct when you first set head=tail=v but it might get wrong later.
int rear() {
if (head == NULL) {
return -1;
}else {
return tail->data;
}
}
Check the if statement below:
v is leaked if queue is full in enqueue in your implementation.
Don't use NULL in C++. You may refer to NULL vs nullptr (Why was it replaced?).
void enqueue(int X) {
Node* v = new Node(X); // new Node
if (n==capacity) { // You're leaking v;
cout << "Full\n";
return;
}
if (head == NULL) {
// Queue is empty
head = tail = v;
}else {
v->next = head;
head = v;
}
}

why i'm getting zero instead of 1?

This is a program of searching a number from linked list using recursion.
#include <iostream>
using namespace std;
class node {
public:
int data;
node *next;
void create(int *,int);
int max(node*,int);
};
node *first;
void node::create(int a[],int n) {
first = new node;
first->data = a[0];
first->next = NULL;
node *last = first;
for (int i = 1; i < n; i++) {
node *t = new node;
t->data = a[i];
t->next = NULL;
last->next = t;
last = t;
}
}
int node::max(node *l, int p) {
if (l->data == p) {
return 1;
}
if (l == 0)
return 0;
else {
max(l->next, p);
return 0;
}
}
int main() {
int a[5] = {1,2,3,4,5};
node m;
m.create(a,5);
cout << m.max(first, 3);
return 0;
}
Hunch. Instead of this:
else {
max(l->next, p);
return 0;
}
This:
else {
return max(l->next, p);
}
Or better yet, let's fix the whole max function to check for null before dereferencing l as well.
int node::max(node *l, int p) {
int result = 0;
if (l != nullptr) {
if (l->data == p) {
result = 1;
}
else {
result = max(l->next, p);
}
}
return result;
}

Unhandled exception in doubly linked lists [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 8 years ago.
Improve this question
I'm attempting to implement a limit order book in C++ (a very simple one) by having a std::map where the keys are price points and the values are PricePoint objects.
The Book class has two of these, bid and ask to store the buys and sells (respectively).
#include <iostream>
#include <map>
#include <list>
using namespace std;
#define MAX_NUM_ORDERS 512
class Order
{
public:
unsigned int id;
unsigned int price;
unsigned int volume;
bool side;
time_t added;
time_t executed;
time_t cancelled;
Order *next;
Order *prev;
Order(unsigned int price, unsigned int volume, bool side)
{
this->id = 0;
this->price = price;
this->volume = volume;
this->side = side;
this->added = 0;
this->executed = 0;
this->cancelled = 0;
this->next = 0;
this->prev = 0;
}
};
class PricePoint
{
public:
Order *head;
Order *tail;
PricePoint(void)
{
this->head = 0;
this->tail = 0;
}
void insertAfter(Order *node, Order new_node)
{
new_node.next = node->next;
if(node->next == 0)
{
this->tail = &new_node;
}
else
{
node->next->prev = &new_node;
}
node->next = &new_node;
}
void insertHead(Order new_node)
{
if(this->head == 0)
{
this->head = &new_node;
this->tail = &new_node;
new_node.prev = 0;
new_node.next = 0;
}
else
{
insertAfter(this->tail, new_node);
}
}
void insertTail(Order new_node)
{
if (this->tail == 0)
{
insertHead(new_node);
}
else
{
insertAfter(this->tail, new_node);
}
}
unsigned int count(void)
{
unsigned int i;
Order node(0, 0, false);
while(node.next == 0)
{
for(i=0;i<=MAX_NUM_ORDERS;i++)
{
// lol
}
}
return i;
}
bool empty(void)
{
if(this->head == 0)
{
return true;
}
else
{
return false;
}
}
void print(void)
{
if(this->empty() == true)
{
cout<<"[None]"<<endl;
return;
}
else
{
if(this->head != 0)
{
unsigned int i;
Order *node = this->head; // start at the head
cout<<"id, volume, added"<<endl; // labels
while(node->next != 0) // while we're not at the end
{
cout<<node->id<<", "<<node->volume<<", "<<node->added<<endl;
node = node->next;
}
}
else // try and catch it again i guess?
{
cout<<"[None]"<<endl;
return;
}
}
}
};
class Book
{
public:
map<int, PricePoint> bid; // buy-side
map<int, PricePoint> ask; // sell-side
int add(Order order)
{
order.id = this->bid.size() + this->ask.size() + 1; // this way, buy-side and sell-side orders have unique identifiers
if(order.side == false) // buy order
{
if(this->bid.count(order.price) == 0) // if the price point isn't already there
{
PricePoint pp;
pair<int, PricePoint> new_pp(order.price, pp);
bid.insert(new_pp); // add the price point (i.e. add an entry to the map)
}
else
{
this->bid[order.price].insertTail(order); // insert at tail of the doubly linked list
}
}
else if(order.side == true) // sell order
{
if(this->bid.count(order.price) == 0)
{
PricePoint pp;
pair<int, PricePoint> new_pp(order.price, pp);
ask.insert(new_pp); // add the price point (i.e. add an entry to the map)
}
{
this->ask[order.price].insertTail(order); // insert at the tail of the doubly linked list
}
}
return order.id; // the order's id
}
int cancel(unsigned int id)
{
}
void print(void)
{
unsigned int i = 0;
cout<<"-------------------------------------BIDS--------------------------------------"<<endl;
cout<<this->bid.size()<<endl;
for(i=0;i<this->bid.size();i++)
{
cout<<"Orders for $"<<i<<":"<<endl;
this->bid[i].print();
}
i = 0;
cout<<endl;
cout<<"-------------------------------------ASKS--------------------------------------"<<endl;
for(i=0;i<this->ask.size();i++)
{
cout<<"Orders for $"<<i<<":"<<endl;
this->ask[i].print();
}
cout<<endl;
}
};
int main(void)
{
unsigned int i;
Book orderbook; // our limit order book
// some orders
Order a(4, 33, false);
Order b(4, 12, true);
Order c(5, 33, true);
//add them
orderbook.add(a);
orderbook.add(b);
orderbook.add(c);
cout<<"Order book is as follows:"<<endl;
orderbook.print();
system("pause");
return 0;
}
I want to print the order book, but when I attempt to traverse the list I am met with unhandled exceptions, like so:
Unhandled exception at 0x00a418aa in orderbook.exe: 0xC0000005: Access violation reading location 0x00000039.
In the debugger, I'm seeing that the next pointer is eventually becoming junk, indicative I've failed to initialise correctly, yes?
Also, the program outputs junk data (also indicative of uninitialised pointers) before excepting.
Any help is much appreciated, thanking you very much.
These:
void insertAfter(Order *node, Order new_node)
void insertHead(Order new_node)
void insertTail(Order new_node)
insert a pointer to a local variable. They have to take a pointer:
void insertAfter(Order *node, Order* new_node)
void insertHead(Order* new_node)
void insertTail(Order* new_node)
try this (and correct it, i guess):
#include <iostream>
#include <map>
#include <list>
using namespace std;
#define MAX_NUM_ORDERS 512
class Order
{
public:
unsigned int id;
unsigned int price;
unsigned int volume;
bool side;
time_t added;
time_t executed;
time_t cancelled;
Order *next;
Order *prev;
Order(unsigned int price, unsigned int volume, bool side)
{
this->id = 0;
this->price = price;
this->volume = volume;
this->side = side;
this->added = 0;
this->executed = 0;
this->cancelled = 0;
this->next = 0;
this->prev = 0;
}
};
class PricePoint
{
public:
Order *head;
Order *tail;
PricePoint(void)
{
this->head = 0;
this->tail = 0;
}
void insertAfter(Order *node, Order* new_node)
{
new_node->next = node->next;
if(node->next == 0)
{
this->tail = new_node;
}
else
{
node->next->prev = new_node;
}
node->next = new_node;
}
void insertHead(Order* new_node)
{
if(this->head == 0)
{
this->head = new_node;
this->tail = new_node;
new_node->prev = 0;
new_node->next = 0;
}
else
{
insertAfter(this->tail, new_node);
}
}
void insertTail(Order* new_node)
{
if (this->tail == 0)
{
insertHead(new_node);
}
else
{
insertAfter(this->tail, new_node);
}
}
unsigned int count(void)
{
unsigned int i;
Order node(0, 0, false);
while(node.next == 0)
{
for(i=0;i<=MAX_NUM_ORDERS;i++)
{
// lol
}
}
return i;
}
bool empty(void)
{
if(this->head == 0)
{
return true;
}
else
{
return false;
}
}
void print(void)
{
if(this->empty() == true)
{
cout<<"[None]"<<endl;
return;
}
else
{
if(this->head != 0)
{
unsigned int i;
Order *node = this->head; // start at the head
cout<<"id, volume, added"<<endl; // labels
while(node->next != 0) // while we're not at the end
{
cout<<node->id<<", "<<node->volume<<", "<<node->added<<endl;
node = node->next;
}
}
else // try and catch it again i guess?
{
cout<<"[None]"<<endl;
return;
}
}
}
};
class Book
{
public:
map<int, PricePoint> bid; // buy-side
map<int, PricePoint> ask; // sell-side
int add(Order order)
{
order.id = this->bid.size() + this->ask.size() + 1; // this way, buy-side and sell-side orders have unique identifiers
if(order.side == false) // buy order
{
if(this->bid.count(order.price) == 0) // if the price point isn't already there
{
PricePoint pp;
pair<int, PricePoint> new_pp(order.price, pp);
bid.insert(new_pp); // add the price point (i.e. add an entry to the map)
}
else
{
this->bid[order.price].insertTail(&order); // insert at tail of the doubly linked list
}
}
else if(order.side == true) // sell order
{
if(this->bid.count(order.price) == 0)
{
PricePoint pp;
pair<int, PricePoint> new_pp(order.price, pp);
ask.insert(new_pp); // add the price point (i.e. add an entry to the map)
}
{
this->ask[order.price].insertTail(&order); // insert at the tail of the doubly linked list
}
}
return order.id; // the order's id
}
int cancel(unsigned int id)
{
}
void print(void)
{
unsigned int i = 0;
cout<<"-------------------------------------BIDS--------------------------------------"<<endl;
cout<<this->bid.size()<<endl;
for(i=0;i<this->bid.size();i++)
{
cout<<"Orders for $"<<i<<":"<<endl;
this->bid[i].print();
}
i = 0;
cout<<endl;
cout<<"-------------------------------------ASKS--------------------------------------"<< ask.size() <<endl;
for(i=0;i<this->ask.size();i++)
{
cout<<"Orders for $"<<i<<":"<<endl;
this->ask[i].print();
}
cout<<endl;
}
};
int main(void)
{
unsigned int i;
Book orderbook; // our limit order book
// some orders
Order a(4, 33, false);
Order b(4, 12, true);
Order c(5, 33, true);
//add them
orderbook.add(a);
orderbook.add(b);
orderbook.add(c);
cout<<"Order book is as follows:"<<endl;
orderbook.print();
// system("pause");
return 0;
}

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(...).