Typedef array referencing? - c++

Hello I have a question regarding the usage of typedef in C++. I am trying to create my own graph class where I can perform DFS and BFS. I have attached what I have for the class so far. But every time I try to compile I run into certain errors that I just do not know how to fix. I am sure the error has something to do with the variable vertexList that I use to hold all the vertices.
#include <iostream>
#include <stack>
class myGraph{
public:
typedef struct Vertex{
char label;
bool visited;
}Vertex;
myGraph(int);
void AddVertex(char);
void addEdge(int, int);
int adjUnvisited(int);
void displayVertex(int);
void dfs();
private:
Vertex* vertexList;
int** adjMatrix;
int size;
int vertices;
int count;
};
myGraph::myGraph(int size){
count = 0;
size = size;
vertices = size;
vertexList = new Vertex[vertices];
adjMatrix = new int*[size];
for(int i=0; i<size; i++){
adjMatrix[i] = new int[vertices];
}
for(int i=0; i<vertices; i++){
for(int j=0; j<vertices; j++){
adjMatrix[i][j] = 0;
}
}
}
void myGraph::AddVertex(char label){
Vertex* myVertex = new Vertex();
myVertex->label = label;
myVertex->visited = false;
vertexList[count++] = myVertex;
}
void myGraph::addEdge(int a, int b){
adjMatrix[a][b] = 1;
adjMatrix[b][a] = 1;
}
int myGraph::adjUnvisited(int index){
for(int i=0; i<vertices; i++){
if(adjMatrix[i][index]==1 && vertexList[i]->visited==false){
return i;
}
}
return -1;
}
void myGraph::displayVertex(int index){
std::cout << "Current vertex: " << vertexList[index]->label << std::endl;
}
void myGraph::dfs(){
std::stack<int> myStack;
int temp = 0;
vertexList[temp]->visited = true;
myStack.push(temp);
int unvisitedVertex;
while(!myStack.empty()){
unvisitedVertex = adjUnvisited[myStack.top()];
if(unvisitedVertex!=-1){
myStack.push(unvisitedVertex);
displayVertex(unvisitedVertex);
vertexList[unvisitedVertex]->visited = true;
}else{
myStack.pop();
}
}
}
The error message that I get is this:
no viable overloaded '=' vertexList[count++] = myVertex;
Along with a note:
candidate function (the implicit copy assignment
operator) not viable: no known conversion from 'struct Vertex *' to
'const myGraph::Vertex' for 1st argument; dereference the argument with *
struct Vertex{
And some other error messages which are (I'm sure these are very minor and I can figure them out):
member reference type 'struct Vertex' is not a
pointer; maybe you meant to use '.'?
if(adjMatrix[i][index]==1 && vertexList[i]->visited==false){
reference to non-static member function must be called
unvisitedVertex = adjUnvisited[myStack.top()];
Now I am not sure what exactly I am doing wrong and was wondering if someone here could help me out.
Thank you very much for all your help!

You've declared vertexList as a pointer-to-Vertex - which is fair enough, since it's going to be an array. But that means that each element of that array is a Vertex structure - yet you're accessing each array element as though it was a pointer.
Either:
Replace all the ->s with .s and do something different in AddVertex()
Declare vertexList as a Vertex ** (like adjMatrix)

Related

free(): invalid pointer error on vector.push_back()

My code gives me free(): invalid pointer error (I don't call free, so my understanding is that it has something to do with how vectors operate internally). I am beginner to C++, so though I checked other answers to similar questions, I fail to see what exactly causes the issue.
I have a grid graph (i.e. vertex is connected with its 4-neighbors). Some vertices hold a special value, which is written done in a file in a form:
row columns value
The code:
graph::graph(const char *file_name) {
ifstream infile(file_name);
istringstream iss;
int R = 2; // number of rows
int C = 4; // number of columns
for (int i=0; i<R*C; i++) add_vertex(i+1);
adj = new std::vector<edge*>[R*C]; // adjacency list
// add all edges to the grid
for (int r=0; r<R; r++) {
for (int c=0; c<C; c++) {
if (c!=C-1) add_edge(vertices[r*C+c], vertices[r*C+(c+1)]);
if (r!=R-1) add_edge(vertices[r*C+c], vertices[(r+1)*C+c]);
}
}
int P = 2; // number of vertices holding a special value
for (int i=0; i<P; i++) {
getline(infile, line);
iss.str(line);
iss >> r >> c >> p;
vertices[r*C+c]->set_value(p);
p_vertices.push_back(vertices[r*C+c]);
iss.clear();
}
void graph::add_vertex(int v) {
auto *vert = new vertex(v);
vertices.push_back(vert);
}
void graph::add_edge(vertex *v, vertex *u) {
edge e = std::make_tuple(v, u, 1);
adj[v->get_id()].push_back(&e);
adj[u->get_id()].push_back(&e);
}
Header:
#include "vertex.h"
typedef std::tuple<vertex*, vertex*, int> edge;
class graph {
private:
std::vector<vertex*> vertices; // all vertices
std::vector<vertex*> p_vertices; // vertices with a special value
std::vector<edge*> *adj; // adjacency list
public:
explicit graph(const char *file_name);
void add_vertex(int v);
void add_edge(vertex *v, vertex *u);
};
Header for a vertex:
#include <string>
#include <vector>
class vertex {
private:
int id;
int val;
public:
explicit vertex(int id) {
this->id = id;
this->val = 0;
};
int get_id() { return id; };
void set_value(int p) { val = p; };
};
Example input:
0 0 1
1 2 3
The error disappears if I comment out this line:
p_vertices.push_back(vertices[r*C+c]);
And remains even if I try to change p_vertices to std::vector<int> instead of std::vector<vertex*> (and use p_vertices.push_back(r*C+c)).
Thanks for any hints on how to fix the error.

How to set an array in a class in C++

I'd like to store an array of numbers in a private variable of a class using a setter method, but am unsure how to.
The program requires a default constructor, and the other essential methods but for simplicity i've only provided the default constructor.
class numberList{
public:
numberList()
{
numberStore = new int[8];
} // default constructor
void setter() // not sure what goes here
{
//not sure what goes here
}
private:
int* numberStore;
};
int main()
{
numberList list1;
list1.setter(1,2,3,4,5,6,7)
}
I'd like for the list1.setter() to take all the values to be put into the array. I think memcpy() could be used here, but am unsure.
I understand there's a concept of operator overloading, but am unsure how utilise this. Any help would be appreciated :-)
EDIT: the assignment requires me not to use standard libraries unfortunately :-(
From your comment that you can't use the STL the solution is to use raw C-pointer arithemtics.
To your setter function you can give a int* pointer and the number of elements:
void setter(int* arr, int n) {
for(int i = 0; i < n; i++)
numberStore[i] = arr[i]
}
Then you can call your setter function in main() like this:
int main() {
numberList list1;
int arr[] = {1,2,3,4,5,6,7};
list1.setter(arr, 7);
}
#include "pch.h"
#include <iostream>
#include <string>
int* my_array = new int[10];
void setter(int* arr, int n)
{
memcpy(&my_array[0], &arr[0], n * sizeof(int));
}
int main()
{
int* arry = new int[10];
for (int i=0; i< 10; i++)
{
arry[i] = i;
}
setter(arry, 10);
for (int i = 0; i < 10; i++)
{
std::cout<<(std::to_string(my_array[i]));
}
}

Access private struct within class c++

Trying to implement an adjacency matrix graph and practice OOP. I've been stuck on implementing the inserNode(string ) method.
My troubles are with accessing the private data fields. What am I completely missing?
Some of the errors:
Graph.cpp:30:26: error: unknown type name 'node'
graph[id] = new node;
^
Graph.cpp:35:10: error: use of undeclared identifier 'numnodes'
numnodes++;
Graph.cpp:34:19: error: expected ';' at end of declaration
graph[id]->nodename = name;
Graph.cpp:34:15: error: decomposition declaration '[id]' requires an initializer
graph.h
#include <iostream>
using namespace std;
class Graph {
public:
Graph();
int insertNode(string name);
private:
static const int vertices = 20;
int nodeCount;
struct node {
int nodeid; // node position in graph[]
string nodename; // username
};
// pointers to the graph nodes
node *graph[vertices];
// adjacency matrix for graph. True if edge is going from node i to j.
bool edges[vertices][vertices];
};
#endif
graph.cpp
#include "Graph.h"
Graph::Graph() {
for (int i = 0; i < vertices; i++) {
graph[i] = 0;
for (int j = 0; j < vertices; j++ )
edges[i][j] = 0;
}
}
/* create node and insert pointer in first available graph position. Returns id value, -1 if unsuccessful. */
int insertNode(string name) {
int id = 0;
while (id < vertices) {
if (graph[id] == NULL) {
graph[id] = new node;
if (!graph[id])
return -1;
graph[id]->nodeid = id;
graph[id]->nodename = name;
numnodes++;
return id;
}
id++;
}
return -1;
}
The insertNode you've defined is not the same way you declared in Graph. You've just made a free function called insertNode, which isn't a member of Graph and therefore can't access Graph. You need to define it like so:
int Graph::insertNode(string name)
{
}

What is right way to access elements of std::array by passing as a pointer to function in C++?

The code snippet is as follows. The error is in foo function for the cout line:
typedef struct Datatype {
int first;
int second;
} Datatype;
void foo(std::array<Datatype, 100>* integerarray){
cout << *integerarray[0].first << endl; //ERROR: has no member first
}
void main() {
std::array<Datatype, 100> newarray;
for(int i=0; i<100; i++)
newarray[i] = i;
}
foo(&newarray);
}
Because of operator precedence, *integerarray[0].first is translated as *(integerarray[0].first), which is not what you want. You need to use (*integerarray)[0].first.
cout << (*integerarray)[0].first << endl;
You can make your life simpler by passing a reference.
void foo(std::array<Datatype, 100>& integerarray){
cout << integerarray[0].first << endl;
}
Also, you don't need to use typedef struct DataType { ... } DataType; in C++. You can use just struct DataType { ... };
newarray[i] = i;
In this line you have missed adding value to structure variables.
Also you have passed array as a reference to function. Removing it and passing just the name of array will pass base address of array.
I am adding following code for your reference:
#include<iostream>
#include <array>
struct Datatype{
int first;
int second;
}
typedef Datatype varInts;
void display(std::array<varInts,20> &dummy)
{
int b =5;
for(int i=0; i<20; i++)
{
dummy[i].first =b++;
dummy[i].second = b+5; //Give any logic you wish.just adding different values;
b++;
}
}
int main()
{
std::array<varInts,20> data;
int a =1;
for(int i=0;i<20;i++)
{
data[i].first = a++;
data[i].second = a+5;
a++; //Just adding values for example
}
display(data);
return 0;
}
It runs without error.Hope it helps!!

Passing an integer pointer to a constructor and getting runtime memory error

I'm trying to create a vector of a class-name vertex. The value of "n" is not known at compile-time so I'll be using new to create to create the "path" array. But the problem occurs when I create the input array in a function and push it in the vector.
int n;
class vertex {
public:
int *path;
int visited = 0;
vertex(int *y) {
path = new int(n);
for (int i = 0; i < n; i++)
path[i] = y[i];
}
};
void inp(vector<vertex> graph) {
int t1[] = { 0,1,0,0 };
int t2[] = { 0,0,1,0 };
int t3[] = { 0,0,0,1 };
int t4[] = { 0,0,0,0 };
graph.push_back(vertex(t1));
graph.push_back(vertex(t2));
graph.push_back(vertex(t3));
graph.push_back(vertex(t4));
}
int main() {
n=4;
vector<vertex> graph;
inp(graph);
_getch();
}
For simplicity I've created t1 to t4 as static arrays. But still it shows some error at runtime
1:try use: path = new int [n], rather than path = new int(n);
2:if you want to push elements to graph, you should change your function inp to void inp(vector<vertex>& graph)