Trying to call a function - c++

So I'm trying to call this function but not too familiar with dynamic data structures and linked lists so I keep getting it wrong. This is my code so far:
struct Country
{
string name;
double population;
};
struct Node
{
Country ctry;
Node * next;
};
Node * world;
void push(Country data, Node * & list);
int main ()
{
Country data;
Node list;
push(data, list);
return 0;
}
What am I doing wrong?

The push function takes a Node*&, which is a "reference to a pointer to a Node" (always read the type backwards, it helps. You are giving it list, which is a Node. The function gets the reference from that call, but you said you would give a reference to a pointer to a Node, so you want to make list in main a Node* and allocate and initialize memory for it, or you want to make another variable that is a Node* and point it to list (Node* ptr = &list;). The first option would be preferable in most cases.

Thanks for comment guys, I changed my code to this and it works now
struct Country
{
string name;
double population;
};
struct Node
{
Country ctry;
Node * next;
};
Node * world;
void push(Country data, Node * & world);
int main ()
{
Country data;
push(data, world);
return 0;
}

Related

Why are changes made to a pointer inside a function not visible outside the function?

I am implementing a linked list. There is a problem: when I change a pointer inside a function, the change is not visible outside of the function.
#include<bits/stdc++.h>
using namespace std;
//define
class List{
public:
int data;
List *next;
public:
List(int n){
this->data=n;
this->next=NULL;
}
};
void add(List *head,int data){
List * nn = new List (data);
head=nn;
}
// driver code
int main(){
List *head=NULL;
List * nn = new List (45);
head=nn;
cout<<head->data;
return 0;
}
This code is printing 45.
class List{
public:
int data;
List *next;
public:
List(int n){
this->data=n;
this->next=NULL;
}
};
void add(List *head,int data){
List * nn = new List (data);
head=nn;
}
// driver code
int main(){
List *head=NULL;
add(head,45);
cout<<head->data;
return 0;
}
This program prints nothing. It simply crashes.
This function:
void add(List *head, int data)
takes the head pointer by copy, so changes to the pointer inside the function are not visible to the caller. This means the pointer head in main is not pointing to valid memory, and dereferencing it invokes undefined behavior (which could cause the crash).
Make the function take the pointer by reference instead:
void add(List * &head, int data)
and now changing head inside the function changes head in the main function.
There are 2 issues in add method:
1) You need to accept pointer to reference (or pointer to pointer)
2) You need to add logic to traversal until the last node in the list and add the new node at the end. Otherwise everytime you are resetting list head with new node and new node is pointing to null and becoming one node list.
Similar implementation you can refer here https://github.com/alokkusingh/DataStructure . The implementation is in C (not C++)

understanding enqueue in a linked list

hey i am trying to add to my queue but I have a problem, and I need some help
i used a linked list for my queue and the problem is when I add a 3rd item to my list I overwrite the second
this is the code
void addnode(node* data)
{
if (begin == NULL)
{
data->next = begin;
begin = data;
}
else
{
end = data; //this is where the problem when i add a 3rd data i dont save anywhere my end so its gone
begin->next = end;
end->next = NULL;
}
}
in my code i have begin for the start of the queue, and end for the end of it
the linked list i built is with classes in c++,
but whenever i add a 3rd data the second gets overwriten so i always have two..
I need some help with how to fix it, thanks :)
edit this is more of the code: this is my class for the queue
#include"node.h"
class queue
{
public:
queue();
~queue();
void addNode(node*);
private:
node* begin;
node* end;
};
this is the class that i get the data from
using namespace std;
class node
{
friend void printclient(node &);
public:
node();
~node();
void setstr(string);
void setmoney(int);
node* next;
private:
string name;
double money;
int id;
};
The function can look the following way. I suppose that the data member next of the node pointed to by the pointer data is already set to nullptr.
void addnode(node* data)
{
if (begin == nullptr)
{
begin = end = data;
}
else
{
end = end->next = data;
}
}
That is if the queue is empty (the pointers begin and end are equal to nullptr) then begin and end are set to the added pointer.
Otherwise the new node is appended to the end of the queue. In this case the data member next of the node pointed to by the pointer end is set to the new pointer and this pointer becomes the end pointer.
Pay attention to that the user of the queue should know nothing about the class node. The class should be declared as a private or protected member of the class queue. And the method addNode should be substitute for the method push declaration of which should look like
void push( const std::string &name, int id, double money );

Linked list overwrites the previous value

I want to create a linked list with classes. I have two classes, one LinkedList and another LinkedNode. My problem is that my function InsertAtEnd always delete the current node. So when I want to print my linked list, I can't see anything.
I know thanks to debugger that in the function InsertAtEnd, we don't enter in the while loop, this is the problem. But after several attemps I can't resolve my problem.
This is my code:
void LinkedList::InsertAtend(int data)
{
LinkedNode* node = new LinkedNode();
node->setData(data); node->setNext(nullptr);
LinkedNode* tmp = _header;
if (tmp != NULL)
{
while (tmp->getNext() != nullptr)
{
tmp = tmp->getNext();
}
tmp->setData(data);
tmp->setNext(nullptr);
}
else
{
_header = node;
}
}
My class LinkedNode:
class LinkedNode
{
public:
LinkedNode();
~LinkedNode();
void setData(int data);
void setNext(LinkedNode* next);
int getData() const;
LinkedNode* getNext() const;
private:
int _data;
LinkedNode* _next;
};
My class LinkedList:
#pragma once
#include
#include "LinkedNode.h"
using namespace std;
class LinkedList
{
public:
LinkedList();
~LinkedList();
void PrintList();
void InsertAtend(int data);
void PrintList() const;
private:
LinkedNode* _header;
};
Thanks for your help !
tmp->setData(data);
Your tmp is not the node that you're trying to add, but the last in your list.
tmp is the last Node, so if you don't want to delete it you shouldn't write value data in it. You should link it with the new Node, which you named node.
Instead of
tmp->setData(data);
tmp->setNext(nullptr);
You should write
tmp->setNext(node)
At the end of the loop, the tmp is the last node in the current list. As you want to add the new node after the last node, you need to
tmp->setNext(node);
to append it (and not set the data as the data are already set to the new node).
Also note that you actually do not need to iterate through the entire list at all, if you keep another member variable to the current end of the list (_tail). Then you can access it directly and simply append and update.

Deleting a custom doubly linked list

List Property:
one pointer pointing to the next node and the other pointer to any arbitrary node in the list.
Structure
struct node
{
int val;
node* link[2];
node(int x);
~node();
};
node :: node(int x)
{
val = x;
link[0] = NULL;
link[1] = NULL;
}
node :: ~node()
{
delete(link[0]);
delete(link[1]);
}
Class
class List
{
node *head, *cloneHead;
node *stack[100];
int childIndex[2][100];
int stptr;
public:
List();
~List();
void createList(int[] , int[][2], int );
int createListStruct(node*);
void createCloneList();
void clone();
void printClone();
};
Creating the list
void List::createList(int a[], int child[][2], int size)
{
node* linkedList[size];
for(int i=0;i<size;i++)
{
linkedList[i] = new node(a[i]);
}
head = linkedList[0];
for(int i=0;i<size;i++)
{
for(int j=0;j<2;j++)
{
if(child[i][j]!=-1)
{
linkedList[i]->link[j] = linkedList[child[i][j]];
}
}
}
}
Main
int main()
{
int a[]={10,1,3,7,2,8,20};
int child[][2] = {{1,4},{1,2},{3,-1},{6,5},{6,5},{-1,0},{5,5}};
int size = sizeof(a)/sizeof(a[0]);
List L;
L.createList(a,child,size);
L.clone();
L.printClone();
return 0;
}
in normal circumstances the destructor work perfectly but for list with the above List property its failing
eg:
Node : 1
Link1 : Node 2
Link2 : Node 3
Node : 2
Link1 : Node 3
Link2 : Node 1
in the above case by the time destructor reaches Link2 of Node2, which point to node 1, node 1 is already deleted, so the code is throwing segmentation error.
I came up with : have a array of unique nodes in list and delete one by one
Is there any other way to do that?
You can use shared_ptr's and they will release memory when the last pointer become destroyed or reassigned. The only thing you have to remember is to avoid cycles, thats why for arbitrary node ponter use weak_ptr instead.
struct node; // forward declaration
struct node
{
int val;
shared_ptr<node> next;
weak_ptr<node> other;
};
2 alternatives to your list idea (which seems ok)
For each Node keep a list of the parents. When a node gets deleted, set all the parents their pointers to that node to nullptr. You can safely delete a nullptr as often as you like.
If your graph is a tree (i.e. without cycles) you can use reference counting using either shared pointers or unique_pointers

Assign the pointer of one class object to another class object c++

so I am very new to C++ programming so I apologize beforehand if I am asking something trivial. My assignment is to add, multiply and evaluate polynomials where each term of a specified polynomial is represented by a Node class with private variables: double coefficient, int power and Node *next.
class Node{
private:
double coef;
int power;
Node *next;
public: blah
}
The head to that linked list (for each polynomial), is to be stored in an array of Poly objects where the only private variable in my Poly class is Node *head.
class Poly{
private:
Node *head;
public:poly functions;
}
The user is to select the polynomial they want to work with by selecting an element from my polynomial array, and this will give the head to the selected polynomial.
poly_array[n];
However my issue now is that the element of this array is of object Poly and I want to make it of class Node so I can actually extract its contents of the class and use this method to transverse through the nodes of the selected polynomial(s).
This is the code I have tried to implement to make this work but my function call of convert poly returns garbage. I am lost as to what method I should try next. Thank you in advance.
This is where I try to first transverse a polynomial to display its contents.
void init_polydisplay(vector<Poly*> polynomial_array, int numofpolys)
{
Poly *polyobject;
Node *polyhead;
for (int n = 0; n < numofpolys; n++)
{
temp3.getnodehead();
polyhead=polyobject->convertPoly(polynomial_array[n]);
}
}
My attempt at trying to return Node* versus just the head of the polynomial.
Node* Poly::convertPoly(Poly* tmp)
{
return (Node *) tmp;
}
You can define a get_head() function in Poly
class Poly{
private:
Node *head;
public:
Node * get_head()
{
return head;
}
};
and use it this way:
polyhead = polynomial_array[n]->get_head();