C++ Need help accessing values inside of linked list - c++

class Node {
public:
Node();
void setNext(Node*);
private:
void* item;
Node* next;
};
void Node::setNext(Node* n)
{
next = n;
}
class List {
public:
List();
void addFirst(void*);
void reset();
void* getCurItem();
private:
Node* head;
Node* current;
};
void List::addFirst(void* obj)
{
Node *newNode = new Node(obj);
newNode->setNext(head);
head = newNode;
}
void List::reset()
{
current = head;
}
void* List::getCurItem()
{
return current->getItem();
}
Polynomial::Polynomial(std::ifstream& input){
List *polyCo = new List();
List *polyEx = new List();
bool exit = false;
double coefficient=0;
int exponent=0;
while(!exit && input.good()){
input >> coefficient;
if(coefficient != -9999.99){
input >> exponent;
cout << "Exponent before: " << exponent << endl;
cout << "Coefficient before: " << coefficient << endl;
int *ExPtr = &exponent;
double *CoPtr = &coefficient;
cout << "Exponent: " << *(ExPtr) << endl;
cout << "Coefficient: " << *(CoPtr) << endl;
polyCo->addFirst(ExPtr);
polyEx->addFirst(CoPtr);
cout << polyCo->getCurItem() << endl; //SEG FAULT
}
}
polyEx->reset();
polyCo->reset();
}
I am reading numbers from a file into two separate linked lists. I am getting a segmentation fault when attempting to access the value in either of the linked list.
First, I'm going to outline how I think my addFirst() functions works, because I could just be implementing it incorrectly. When addFirst() is called, a new node is created, and the data being read in is set equal to the member of the new node. The existing node in the list is pushed forward, and the new node created becomes the head. The two nodes are also linked.
There could be something else entirely wrong besides my implementation of the function, but at least it is a good place to start, along with the source of the segmentation fault.

Related

C++ Read Access Violation in Singly Linked List

I'm writing a program about creating a list of country, there seems to no error in my code but when debugging, I get the error: Unhandled exception thrown: Read access violation p was 0xFFFFFFFFFFFFFFFF, after I input some values.
Can anyone give me a hint or find me the mistake?
#include <cstring>
#include <string>
using namespace std;
this is my struct Provice.
struct Province
{
int Code;
string Name;
int Pop;
float Area;
};
struct node
{
struct Province data;
node* next;
};
struct List
{
node* head;
node* tail;
};
void Init(List &l)
{
l.head = NULL;
l.tail = NULL;
}
void add_tail(List& l, node* p)
{
if (l.head == NULL)
{
l.head = p;
l.tail = p;
}
else
{
l.tail->next = p;
l.tail = p;
}
}
I think I got some problem when I create a node here without initializing value, is this right ?
void inputListProvinces(List& l)
{
int n;
cin >> n;
int i = 0;
while(i<n)
{
node* p = new node;
cin >> p->data.Code;
cin.ignore();
getline(cin, p->data.Name);
cin.ignore();
cin >> p->data.Pop;
cin >> p->data.Area;
add_tail(l, p);
i++;
}
}
And the error happens here, but I dont know how to fix.
void outputListProvinces(List& l)
{
node* p = l.head;
while (p != NULL)
{
cout << p->data.Code << '\t'; /*Unhandled exception thrown: read access violation.
p was 0xFFFFFFFFFFFFFFFF*/
cout << p->data.Name << '\t';
cout << p->data.Pop << '\t';
cout << p->data.Area << '\t';
cout << endl;
p = p->next;
}
}
void outputProvince(node* p)
{
cout << p->data.Code << '\t';
cout << p->data.Name << '\t';
cout << p->data.Pop << '\t';
cout << p->data.Area << '\t';
}
void outputProvincesMore1MillionPop(List& l)
{
node* p = l.head;
while (p != NULL)
{
if (p->data.Pop > 1000)
{
outputProvince(p);
cout << endl;
}
p = p->next;
}
}
node* findProMaxArea(List& l)
{
node* n = l.head;
node* p = l.head;
while (p != NULL)
{
if (p->data.Area > n->data.Area)
{
n = p;
}
p = p->next;
}
return n;
}
int main()
{
List L;
Init(L);
inputListProvinces(L);
cout << "List of provinces:" << endl;
cout << "ID\t|Province\t|Population\t|Area" << endl;
outputListProvinces(L);
cout << "Provinces with a population of more than 1 million:" << endl;
outputProvincesMore1MillionPop(L);
cout << "The largest province:" << endl;
node* p = findProMaxArea(L);
if (p) outputProvince(p);
return 0;
}
Mistake is node never initializes its next pointer. You can only count on it being NULL if you set it to NULL, and the last node in the list MUST be NULLor the program can't find the end of the List and marches off into the wacky world of Undefined Behaviour.
Safest Fix: Add a constructor to node to make sure next is always initialized.
struct node
{
struct Province data;
node* next;
node(node* n = NULL): next(n)
{
}
};
There are other fixes, like making sure l.tail->next = NULL; at the end of inputListProvinces, but I don't think it's really worth the reduced overhead given the slow-ness of the console IO.
And if you do that, then you should also roll Init into List as a constructor:
struct List
{
node* head;
node* tail;
List(): head(NULL), tail(NULL)
{
}
};
This should leave you with the problem of a poorly-placed cin.ignore() consuming a character you don't want consumed.
Side note: Replace NULL with nullptr if available to your compiler and target C++ Standard revision. nullptr removes the bugs that can result from NULL being a glorified 0.

How to generate unique ID in linked list?

I am currently learning how to use linked list in class in my free time. Now I only know how to insert, display and delete. I can delete by using int age; but I think it would be better if I'm able to generate a unique ID that is easier for user to remember(user-friendly), for each data in the linked list so that I could delete by its ID.
I want to know if there is a possible way for me to generate a unique ID in the getInput(); function?
If yes, please give me a hint how to do it. Thanks!
struct list
{
list *head, *tail;
list *next;
}
class node
{
private:
std::string name; // Name
int age; // Age in integer
float height; // In meters
public:
node *next; // Pointer to next node
node *head, *tail;
node *start_ptr = NULL; // Start Pointer (root)
node *temp;
node *temp2;
node *pNextValue;
node* prev; // empty header
node* current;
void printList();
void delete_end_node();
void search();
void sort_age();
void deletebyAge();
node()
{
head = NULL;
tail = NULL;
}
void getInput()
{
temp = new node;
cout << "ID: ";
// This is where I want to generate unique ID
cout << "Name: ";
cin >> temp->name;
cout << "Age: ";
cin >> temp->age;
cout << "Height: ";
cin >> temp->height;
cout<<"\n";
temp->next = NULL; // Sets the node to be the last node
if (start_ptr == NULL)
start_ptr = temp;
else
{
temp2 = start_ptr; // We know temp2 is not NULL - list not empty!
while (temp2->next != NULL) // The loop will terminate when temp2
temp2 = temp2->next; // points to the last node in the list
// Move to next link in chain
temp2->next = temp; // Sets the pointer from that last node to point to the node that has just declared
}
} // End of getInput() function
}; //End of class
In C++ the identity of an object is its address. You can use node address as its id, e.g.:
class node
{
private:
std::string name; // Name
int age; // Age in integer
float height; // In meters
friend std::ostream& operator<<(std::ostream& s, node& n) {
return s << "id:" << &n
<< ' ' << "name:" << n.name
<< ' ' << "age:" << n.age
<< ' ' << "height:" << n.height
<< '\n';
}
// the rest of your code...
};
And then print it like:
node n;
std::cout << n;
Alternatively, use a serial counter:
class node
{
private:
std::string name; // Name
int age; // Age in integer
float height; // In meters
unsigned const id;
static unsigned object_counter;
public:
node()
: id(++object_counter)
{}
friend std::ostream& operator<<(std::ostream& s, node& n) {
return s << "id:" << n.id
<< ' ' << "name:" << n.name
<< ' ' << "age:" << n.age
<< ' ' << "height:" << n.height
<< '\n';
}
// the rest of your code...
};
unsigned node::object_counter = 0;

How to use a reference to a pointer in a C++ function?

I'm trying to implement a simple linked list. I need an insert function that takes a value and a node to insert after, so I have this:
#include <iostream>
using namespace std;
typedef struct node node;
struct node {
int data;
node * next = NULL;
};
void insert(node *& head, int value, node *& insert_after_me) {
node n; n.data = value;
node * new_node = &n;
if (insert_after_me == NULL) {
insert_after_me = new_node;
cout << "after assign insert: " << insert_after_me->data << endl;
head = new_node;
cout << "after assign head: " << head->data << endl;
}
}
int main () {
node * head = NULL;
node * new_node = NULL;
insert(head, 1, new_node);
cout << head->data << endl;
cout << new_node->data << endl;
cout << head << endl;
cout << new_node << endl;
}
This is obviously an imcomplete implementation, but when I run it I get the following as output:
after assign insert: 1
after assign head: 1
1
1924530936
0x7fff56177928
0x7fff56177928
This tells me in main, head and new_node are pointing to the same thing, yet they have different values stored in data. Why?
Note: Though it seems to me a nonsensical implementation to make insert take a node to insert after and then change that node, that's a requirement of the project. I can't change how insert is called.

C++ Priority Queue Class with Linked List

I am having two issues with my c++ code (The test file is below):
I can't seem to figure out why its not breaking out of the while loop, when running, its stuck on the loop "7 versus 325".
So it should go into the next node of temp, which would be null, and then jump into the section where it adds it to the end of the queue. But its just looping and looping.
My second issue is with the the function I have commented out, queue1.back, whenever that is ran, it just errors out and gives what appears to be the address, but the .front() function works just fine.
The Test File I am working with is like this:
89 Alex
325 Rob
72 Joy
91 Bob
using namespace std;
class Person
{
friend class Pqueue;
public:
int priority;
string name;
};
class PQueue
{
friend class Person;
private:
//Structure for my linked list.
typedef struct node {
Person data;
struct node *next;
}Node, *NodePtr;
Node *head, *tail;
public:
//Prototype Functions
PQueue(void); //Initializer function
bool empty(void); //Test if empty
int size(void); //Return size
void enqueue(Person *); //Insert Node
void dequeue(void); //Remove Node
Person* front(void); //Access Next Node
Person* back(void); //Access last node
};
PQueue::PQueue()
{
head = NULL;
tail = NULL;
}
bool PQueue::empty(){
return (head == NULL);
}
void PQueue::enqueue(Person *myPerson){
NodePtr np = (NodePtr) malloc(sizeof(Node));
np->data = *myPerson;
np->next = NULL;
if(empty())
{
cout << "Making into creating the first node, of the linked list" <<endl;
head = np;
tail = np;
}
else { //Queue has more the one node
Node* temp = head;
if(np->data.priority > temp->data.priority) //If the priority is greater then the rest.
{
head = temp; //Saving my head pointer
head->data = np->data; //Assigning new Data to the head pointer
head->next = temp; //Assigning the rest of the linked list back into head.
cout << "Making into creating the first node again, having to reassign." <<endl;
}
else{
//Searching where to place the node.
while(temp->data.priority > np->data.priority) //Searching if the next priority is higher then the passed.
{
cout << "Inside the while loop: " << np->data.priority << " versus "<<temp->data.priority <<endl;
if(temp->next == NULL)
break;
temp = temp->next;
}
if(temp->next == NULL && np->data.priority < temp->data.priority) //Inserting at the end.
{
cout << "Making into creating the last node" <<endl;
tail->next = np;
cout << "Passing the function of creating the last node" <<endl;
}
else //Inserting into the middle of the function.
{
cout << "Inserting in the middle of the queue" <<endl;
np->next = temp->next;
temp->next = np;
}
}
}
}
void PQueue::dequeue(){
if(empty()){
cout << "\nAttempt to remove from an empty list." << endl;
exit(1);
}
Person hold = head->data;
NodePtr temp = head;
head=head->next;
if (head == NULL) tail = NULL;
free(temp);
}
Person* PQueue::front(){
//Person &temp = head->next->data;
//Person &temp = head->data;
Person &temp = head->data;
return &temp;
}
Person* PQueue::back(){
if(empty()){
cout << "\nNo entries in list." << endl;
exit(1);
}
Person &temp = tail->data;
return &temp;
}
int main() {
cout << "Starting main" << endl;
PQueue queue1; //Creating my queue.
cout << "Created Queue" << endl;
Person tempPerson;
ifstream inFile;
inFile.open("/tmp/temp");
cout << "going into while loop" << endl;
while (inFile >> tempPerson.priority >> tempPerson.name){
cout << "The priority is " << tempPerson.priority << " the name is " << tempPerson.name <<endl;
queue1.enqueue(&tempPerson);
}
//Testing Section, trying to get .front and .back to work.
Person *testPerson;
testPerson = queue1.front();
cout << "The TEST priority is " << testPerson->priority << " the TEST name is " << testPerson->name <<endl;
/**
Person *tailPerson;
testPerson = queue1.back();
cout << "The TEST priority is " << tailPerson->priority << " the TEST name is " << tailPerson->name <<endl;
**/
queue1.dequeue();
queue1.dequeue();
queue1.dequeue();
return 0;
}
When you add a new head entry to a non-empty list, you're mistakenly setting the next pointer to point right back at the node it's in, rather than setting it to point at the rest of the linked list like you intended.
head = temp; //Saving my head pointer
head->next = temp; //Assigning the rest of the linked list back into head.

Delete a specific node in a Linked list using STL

struct node
{
int data;
node* next;
};
class linklist
{
node* head;
public:
linklist(){ head = NULL;}
void Delete_a_Node( ? , ? ); \\ Not getting how to call this function
};
int main()
{
list<int> l1;
linklist ll1;
.
.
.
for (int i = 0; i < no; i++)
{
cin >> element;
l1.push_back(element);
}
cout << "Original list: " << endl;
list<int>::iterator p = l1.begin(); // Printing List elements.
while (p != l1.end()){
cout << *p << " ";
p++;
}
cout << endl << endl;
cout << "which node do you want to delete" << endl;
cin >> m;
ll1.Delete_a_Node(m, p); \\ Getting Error
_getch();
return 0;
}
Here ,I have created a list using list class. Now I want to delete specific node ( 2nd, or 3rd, or anything ) without using list class member functions. But not getting how to call Delete_a_Node() function.
How to pass Head ( in which address of starting node is stored ) node ??
I want to learn STL, so used class list and iterator purposely.