value lost after assignment in a pointer - c++

This code is printing 0 for this->min_node->right and this->min_node->left in the function add_node_to_the_list. I am not able to figure out why it is happening when I have assigned some values to this variables in previous iterations. This value is available when I am printing it in the main but after calling the function this value is lost.
#include<iostream>
#include<vector>
#include<iterator>
namespace a1{
/******************************Declarations*********************************/
class node{
//Private member declaration
//Public member declaration
public: int key;
public: int degree;
public: bool mark;
public: node * left;
public: node * right;
public: node * child;
public: node * parent;
//Private method declaration
//Public method declaration
public: node(int);
};
class heap{
//Private member declaration
private: int node_count;
private: void add_node_to_the_list(node *);
//Public member declaration
public: node * min_node;
//Private method declaration
private: void consolidate();
private: void fib_heap_link(node *, node *);
private: void cut(node *, node *);
private: void cascading_cut(node *);
//Public method declaration
public: heap();
public: void fib_heap_insert(int);
public: void fib_heap_union(heap &);
public: heap & fib_heap_extract_min();
public: void fib_heap_decrease_key(node *, int);
public: void fib_heap_delete(node *);
public: int get_node_count();
};
};//End of namespace a1
/****************************Definitions*************************************/
/****************************node functions here*****************************/
a1::node::node(int key){
this->key = key;
this->degree = 0;
this->mark = false;
this->left = NULL;
this->right = NULL;
this->child = NULL;
this->parent = NULL;
}
/****************************Heap functions here*****************************/
//Private methods
void a1::heap::add_node_to_the_list(node * temp){
if(this->min_node == NULL){
this->min_node = temp;
this->min_node->right = this->min_node;
this->min_node->left = this->min_node;
}
else{
temp->right = this->min_node->right;
temp->left = this->min_node;
//this->min_node->right->left = temp;
//this->min_node->right = temp;
}
}
//Public methods
a1::heap::heap(){
this->node_count = 0;
this->min_node = NULL;
}
void a1::heap::fib_heap_insert(int key){
a1::node temp(key);
if(this->min_node == NULL){
a1::heap::add_node_to_the_list(&temp);
this->min_node = &temp;
}
else{
std::cout << "Printing this->min_node->right : " << this->min_node->right << std::endl;
std::cout << "Printing this->min_node->left : " << this->min_node->left << std::endl;
a1::heap::add_node_to_the_list(&temp);
if(this->min_node->key > temp.key){
this->min_node = &temp;
}
}
this->node_count += 1;
}
int a1::heap::get_node_count(){
return this->node_count;
}
/**************************Debug functions***********************************/
using namespace a1;
void print_fib_heap(node * n){
if(n == NULL) return;
else{
node * min_node;
node * trav;
bool flag = false;
min_node = n;
trav = n;
while(flag == false || trav != min_node){
flag = true;
std::cout << "(" << "key = " << trav->key << " d = " << trav->degree;
print_fib_heap(trav->child);
std::cout << ")";
trav = trav->right;
}
}
}
/**************************Main Function to test*****************************/
int main(){
heap h1;
h1.fib_heap_insert(2);
std::cout << "From main h1.min_node->right: " << h1.min_node->right << std::endl;
h1.fib_heap_insert(3);
//print_fib_heap(h1.min_node);
return 0;
}

this->min_node = &temp is saving the address of a local stack variable, which won't be valid as soon as the method returns. The results would then be undefined.
I would suggest using new for that object in a1::heap::fib_heap_insert().

Related

Adding nodes in a singly linked list using oop

i have an assigment where i have to work with singly linked list using oop. I got stuck mostly on the sortedInsert function. I am assuming it will be some mistake with using pointers but I can't figure it out. And the program crashes after entering the user input in the for loop in initializeList function it might be because of the sortedInsert function but maybe it's something else.
Can someone help me figure out where am I getting it worng?
Here is the code:
#include <iostream>
using namespace std;
class Item{
private:
int m_value;
Item* m_next;
public:
Item(int val){
m_value = val;
m_next = NULL;
};
int getValue(){ return this->m_value; };
Item* getNext() { return this->m_next; };
void setValue(int val){ m_value = val; };
void setNext(Item* nxt){ m_next = nxt; };
};
class IntList{
private:
Item* m_front = NULL;
Item* m_end;
int m_size = 0;
void bump_up(int m_size){ m_size++; };
void bump_down(int m_size){ m_size--; };
public:
IntList(){ m_front = NULL; };
Item* getFirst(){ return this->m_front; };
//int getValueFirst(){ return this->firstItem->getValue(); };
~IntList();
void sortedInsert(Item* first, int val){
Item* newItem = new Item(val);
Item* current;
if(first == NULL || (first)->getValue() >= newItem->getValue()){
newItem->setNext(first);
first = newItem;
}
else{
current = first;
while(current->getNext() != NULL && current->getNext()->getValue() < newItem->getValue()){
current = current->getNext();
}
newItem->setNext(current->getNext());
current->setNext(newItem);
}
bump_up(m_size);
}
//print
void display(){
Item* p = m_front;
cout << "(" << m_size << ")";
while(p != NULL){
cout << p->getValue() << " ";
p = p->getNext();
}
cout << endl;
}
void initializeList(IntList* list){
int x, i;
cout << "Insert list size: ";
cin >> x;
cout << "Insert " << x << " numbers, which will be put in the list:";
for(i = 0; i <= x; i++){
int a;
cin >> a;
list->sortedInsert(list->getFirst(), a);
}
//cout << endl;
}
int main()
{
IntList* list = new IntList();
initializeList(list);
list->display();
return 0;
}

A reference of type "Bucket&" (not const qualified) cannot be initialized with a value of type "SortedList." How can this error be fixed?

The error occurs in my SortedList class in function method sortList. I have tried to rename, remove, move, and manipulate certain things to no avail. I will show you a good amount of code so that you can see where I'm coming from.
void SortedList::sortList(const vector <double>& list) {
BucketSort bucketA;
bucketA.insert(list);
bucketA.createSortedList(*this); // <--- Problem here, on this one line.
// The * is highlighted in red in my IDE.
}
Error: A reference of type "Bucket&" (not const qualified) cannot be initialized with a value of type "SortedList"
For reference, if you need to see to get a context of my error:
SortedList.h:
#ifndef SORTEDLIST_H
#define SORTEDLIST_H
#include "bucketsort.h"
#include <vector>
using namespace std;
class SortedList
{
public:
SortedList();
void sortList(const vector <double>& list);
~SortedList();
private:
};
#endif
Bucketsort.h:
#ifndef BUCKETSORT_H
#define BUCKETSORT_H
#include "bucket.h"
#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;
const int DEFAULTCAPACITY = 10;
class BucketSort
{
public:
// Constructors:
BucketSort();
// Functions:
void print() const;
void insert(const vector <double>& v) const;
void createSortedList(Bucket& a);
//
~BucketSort();
private:
Bucket ** a;
};
#endif
Bucketsort.cpp:
#include "bucketsort.h"
BucketSort::BucketSort() {
a = new Bucket*[DEFAULTCAPACITY]();
}
void BucketSort::print() const {
for (int i = 0; i < DEFAULTCAPACITY; ++i) {
if (a[i] != nullptr) {
a[i]->print();
}
}
}
void BucketSort::insert(const vector <double>& v) const {
int index;
for (int i = 0; i < v.size(); ++i) {
index = v[i] * 10;
if (a[index] == nullptr) {
Bucket* newBucket = new Bucket;
a[index] = newBucket;
}
a[index]->insert(v[i]);
}
}
void BucketSort::createSortedList(Bucket& a){
}
BucketSort::~BucketSort() {
for (int i = 0; i < DEFAULTCAPACITY; ++i) {
if (a[i] != nullptr) {
a[i]->deleteBucket();
}
}
delete a;
a = nullptr;
}
Bucket.h:
#ifndef BUCKET_H
#define BUCKET_H
#include <iostream>
using namespace std;
class Node
{
public:
Node() : item(0.0), link(nullptr) {}
Node(double newItem, Node *newLink) : item(newItem), link(newLink) {}
Node* getLink() const { return link; }
double getItem() const { return item; }
void setItem(double newItem) { item = newItem; }
void setLink(Node *newLink) { link = newLink; }
~Node() {}
private:
double item;
Node *link;
};
class Bucket
{
public:
Bucket();
void insert(double value);
void testPrint() const;
void print() const;
int getNumberOfElements() const;
void deleteBucket();
~Bucket();
private:
Node * ptrToFirst;
Node *ptrToLast;
int numberOfElements;
};
#endif
Bucket.cpp:
#include "bucket.h"
Bucket::Bucket() {
ptrToFirst = nullptr;
ptrToLast = nullptr;
numberOfElements = 0;
}
void Bucket::insert(double value) {
if (numberOfElements != 0) {
Node *newNode = new Node(value, nullptr);
if (value < ptrToFirst->getItem()) {
newNode->setLink(ptrToFirst);
ptrToFirst = newNode;
}
else if (value > ptrToLast->getItem()) {
ptrToLast->setLink(newNode);
ptrToLast = newNode;
}
else if (value != ptrToFirst->getItem()) {
Node *current = ptrToFirst;
while (value > current->getLink()->getItem()) {
current = current->getLink();
}
if (current->getLink()->getItem() != value) {
newNode->setLink(current->getLink());
current->setLink(newNode);
}
}
}
else {
ptrToFirst = new Node(value, ptrToLast);
ptrToLast = ptrToFirst;
}
++numberOfElements;
}
void Bucket::testPrint() const {
cout << "Pointer to first: " << ptrToFirst << endl;
cout << "Pointer to last: " << ptrToLast << endl;
if (ptrToFirst != nullptr && ptrToLast != nullptr) {
cout << "Value of ptrToFirst: " << ptrToFirst->getItem() << endl;
cout << "Value of ptrToLast: " << ptrToLast->getItem() << endl;
}
cout << "Number of elements: " << numberOfElements << endl;
cout << "Contents of bucket: " << endl;
Node *current = ptrToFirst;
while (current != nullptr) {
cout << current->getItem() << " ";
current = current->getLink();
}
cout << endl;
}
void Bucket::print() const {
Node *current = ptrToFirst;
while (current != nullptr) {
cout << current->getItem() << " ";
current = current->getLink();
}
}
int Bucket::getNumberOfElements() const {
return numberOfElements;
}
void Bucket::deleteBucket() {
Node *trailingCurrent;
while (ptrToFirst != nullptr) {
trailingCurrent = ptrToFirst;
ptrToFirst = ptrToFirst->getLink();
delete trailingCurrent;
trailingCurrent = nullptr;
}
ptrToLast = nullptr;
numberOfElements = 0;
}
Bucket::~Bucket() {
deleteBucket();
}
Help?
void SortedList::sortList(const vector <double>& list) {
[...]
bucketA.createSortedList(*this); // <--- Problem here
In the above line, this is of type SortedList *, so *this is of type SortedList &.
... and yet, your createdSortedList method requires an argument of a different type, Bucket &:
void createSortedList(Bucket& a);
Since a SortedList and a Bucket are not the same type, and there is no way (that the compiler knows about) to convert a SortedList object into a Bucket object, the compiler is rightly flagging the call as an error.
To solve the problem, you either need to change createSortedList to take a SortedList & as its argument, instead of a Bucket &, or change your call to pass in a Bucket & instead of a SortedList &.

c++ : Expression must be a modifiable lvalue

I got
Expression must be a modifiable lvalue
in
rear->getNextNode() = &node;
Here is code:
using namespace std;
#include<iostream>
#include<string>
class Node
{
string name;
Node* next;
int arrivedTime;
int runningTime;
char state='R';
public:
Node(char* name,int arrivedTime,int runningTime):name(name),arrivedTime(arrivedTime),runningTime(runningTime){}
void printState()
{
cout << "name=" << name << " " << endl;
}
void execute()
{
runningTime--;
printState();
}
bool whetherArrive()
{
if (arrivedTime > 0)
{
return false;
}
else
{
return true;
}
}
void downArrivedTime()
{
arrivedTime--;
}
Node* getNextNode()
{
return next;
}
};
class Queue
{
public:
Node* head;
Node* rear;
Node* p;
void insert(Node &node)
{
if (head == NULL)
{
head = &node;
rear = &node;
p = &node;
}
else
{
rear->getNextNode() = &node; //here hint Expression must be a modifiable lvalue
}
}
};
int main()
{
cout << "input: process-count" << endl;
int processCount;
cin >> processCount;
for (int i = 0; i < processCount; i++)
{
cout << "input:process-name arrivedTime runningTime" << endl;
char name[20];
int arrivedTime;
int runningTime;
cin >> name >> arrivedTime >> runningTime;
Node node(name, arrivedTime, runningTime);
}
}
rear->getNextNode() return a pointer to Node, and then set the point &node. What's wrong here?
As in the error, to make this compile:
rear->getNextNode() = &node;
getNextNode() must return lvalue so you need to modify singature to:
Node*& getNextNode()
^

Search Function Using Derived Classes in a Hash Table

I am having a bit of an issue with my derived classes and how they utilize the search function that they inherit from their parent class.
Here is my .h file
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
#define TABLESIZE 13
#ifndef HASH_H
#define HASH_H
namespace HTGroup
{
template<class T>
class HashTable
{
protected:
struct item {
T x;
item* next;
};
item* HT[TABLESIZE];
virtual int hash(T key) = 0;
virtual int collision(T key, int &value) = 0;
public:
HashTable();
virtual void printGrid();
void insert(T key);
void remove(T key);
void search(T key);
int indexItems(int index);
};
template<class T>
class DHT1 : public HashTable<T>
{
protected:
int hash(T key);
int collision(T key, int &value);
struct item {
T x;
item* next;
};
item* HT[TABLESIZE];
public:
DHT1();
void printGrid();
};
template<class T>
class DHT2 : public HashTable<T>
{
protected:
int hash(T key);
int collision(T key, int &value);
struct item {
T x;
item* next;
};
item* HT[TABLESIZE];
public:
DHT2();
void printGrid();
};
}
#endif
Here is what I have implemented for the search function:
template<class T>
void HashTable<T>::search(T key)
{
int index = hash(key);
bool foundKey = false;
string item;
item* temp = HT[index];
while(temp != NULL)
{
if(temp->x == key)
{
foundKey = true;
item = temp->x;
}
temp = temp->next;
}
if(foundKey == true)
{
cout << "Item was found." << endl;
}
else
{
cout << "Item was not found." << endl;
}
}
And this is how I am calling the function in my main:
hashy1.search(item);
I am getting an error from the compiler with this line from my search implementation:
item* temp = HT[index];
Giving me this error:
[Error] 'temp' was not declared in this scope
From my understanding whenever an object of a derived class is calling the search function it is getting confused with whether or not the pointer created is of the parent class or the derived class.
The weird thing though is that it has let me create other pointers in my remove function without any issues and it works fine:
template<class T>
void HashTable<T>::remove(T key)
{
int index = hash(key);
item* delPtr; //Where I am allowed to create pointers with
item* P1; //no issues
item* P2;
if(HT[index]->x == "")
{
cout << key << " was not found in the hash table" << endl;
}
else if ( HT[index]->x == key && HT[index]->next == NULL)
{
HT[index]->x = "";
cout << key << " was removed from the hash table" << endl;
}
else if(HT[index]->x == key)
{
delPtr = HT[index];
HT[index] = HT[index]->next;
delete delPtr;
cout << key << " was removed from the hash table" << endl;
}
else
{
P1 = HT[index]->next;
P2 = HT[index];
while(P1 != NULL && P1->x != key)
{
P2 = P1;
P1 = P1->next;
}
if(P1 == NULL)
{
cout << key << " was not found in the hash table" << endl;
}
else
{
delPtr = P1;
P1 = P1->next;
P2->next = P1;
delete delPtr;
cout << key << " was removed from the hash table" << endl;
}
}
}
I've tried creating the pointer in the .h file like this:
template<class T>
class DHT1 : public HashTable<T>
{
protected:
int hash(T key);
int collision(T key, int &value);
struct item {
T x;
item* next;
item* temp; // Added declaration
};
item* HT[TABLESIZE];
public:
DHT1();
void printGrid();
};
But that still gives me declaration issues
Are there different methods I should be using when implementing my search function such as any extra parameters in the function call? Or maybe I am just not getting the logic down right?
Thank you for any responses!
You declared item as a std::string, and then you use item in the same scope as a type.
string item; // <-- declaring as string
item* temp = HT[index]; // <-- Compiler doesn't know what to do with this line except to give an error.
The simplest solution is to name your std::string variable something else other than item.

C++ Priority Queue crashes when I insert elements

I made up a priority-queue through a Min Heap.
This is a PriorityQueue of pointers to the class Node.
When I try to create a PriorityQueue object trough the vector it works great. The problem is inserting the pointers to Node individually through Insert method. It also works and prints the priority-queue but sometimes it crashes at the end of the execution! It returns an error despite works good.
Output:
a 1
b 2
c 3
Process returned -1073741819 (0xC0000005) execution time : 3.000 s
Press any key to continue.
Main:
int main()
{
NODE a = new Node('a',1);
NODE b = new Node('b',2);
NODE c = new Node('c',3);
Q.Insert(a);
Q.Insert(b);
Q.Insert(c);
Q.Print();
return 0;
}
Node code:
typedef class Node *NODE;
class Node {
private:
unsigned char Ch;
int Key;
NODE L;
NODE R;
public:
Node() { L = NULL; R = NULL; };
Node(int, unsigned char, NODE, NODE);
Node(unsigned char, int);
~Node() { delete L; delete R; };
NODE Left();
NODE Right();
int GetKey();
unsigned char GetChar();
void SetKey(int);
void SetChar(unsigned char);
};
Node::Node(unsigned char c, int k)
{
Ch = c; Key = k; R = NULL; L = NULL;
}
NODE Node::Left()
{
return L;
}
NODE Node::Right()
{
return R;
}
unsigned char Node::GetChar()
{
return Ch;
}
int Node::GetKey()
{
return Key;
}
void Node::SetKey(int k)
{
Key = k;
}
PriorityQueue code:
class PriorityQueue {
private:
vector<NODE> A;
int Heap_Size;
int Parent(int);
int Left(int);
int Right(int);
void Swap(NODE &, NODE &);
void MinHeapify(int);
public:
PriorityQueue();
PriorityQueue(vector<NODE>);
~PriorityQueue() {};
NODE Minimum();
NODE ExtractMin();
void DecreaseKey(int, int);
void Insert(NODE);
bool IsEmpty();
void Print();
};
PriorityQueue::PriorityQueue()
{
// I need to push back an empty node to use the vector from the index 1.
// This is important to move in the min-heap trough the indices.
NODE Default = new Node;
A.push_back(Default);
Heap_Size = 0;
}
PriorityQueue::PriorityQueue(vector<NODE> vett)
{
A = vett; Heap_Size = A.size()-1;
for (int i=Heap_Size/2; i>=1; i--)
{
MinHeapify(i);
}
}
void PriorityQueue::Swap(NODE &a, NODE &b)
{
NODE temp = a;
a = b;
b = temp;
}
void PriorityQueue::DecreaseKey(int i, int key)
{
if (key > A[i]->GetKey())
{
cout << "How can I decrease the key?" << endl;
return;
}
A[i]->SetKey(key);
while (i>1 && A[Parent(i)]->GetKey() > A[i]->GetKey())
{
Swap(A[i],A[Parent(i)]);
i = Parent(i);
}
}
void PriorityQueue::Insert(NODE Nodo)
{
Heap_Size++;
A[Heap_Size] = Nodo;
DecreaseKey(Heap_Size,Nodo->GetKey());
}
void PriorityQueue::Print()
{
for (int i=1; i<=Heap_Size; i++)
cout << A[i]->GetChar() << " " << A[i]->GetKey() << endl;
}
Thank you very much!!!!
I solved it! The problem was:
Heap_Size++;
A[Heap_Size] = Nodo;
A is a vector, so I had to edit in this way:
A.push_back(Nodo);