I am trying to implement stack using linked list and class, and to the stack class constructor, I am giving reference variables as arguments with default value 0. But it shows an error when I do push operation with an integer literal. How can I implement it by using a default value and reference variable as well?
// ***** Stack using linked list ****
#include <iostream>
using namespace std;
class node{
node* next;
int data;
public:
node(int &d=0,node* n=NULL):data(d),next(n){}
node(){}
~ node(){}
friend class stack0;
};
class stack0{
int size;
node* head;
public:
stack0(){}
stack0():size(-1),head( new node() ){}
void push(int &t){
if (size == -1){
head->data=t;
cout<<"& pushed "<<t<<" at "<<head<<" with size "<<size;
size++;
}
else{
node* temp;temp=head;
head = new node(t,head);
cout<<"& pushed "<<t<<" at "<<head<<" with size "<<size;
head->next=temp;
size++;
}
}
};
int main(){
stack0 s;
s.push(10);
return 0;
}
Related
When I run my code with the below implementation of the Constructor of LRUCache class, I get 12 compiler warnings as follows:
The same set of first six warnings is repeated again.
struct Node{
Node* next;
Node* prev;
int value;
int key;
Node(Node* p, Node* n, int k, int val):prev(p),next(n),key(k),value(val){};
Node(int k, int val):prev(NULL),next(NULL),key(k),value(val){};
};
class Cache{
protected:
map<int,Node*> mp; //map the key to the node in the linked list
int cp; //capacity
Node* tail; // double linked list tail pointer
Node* head; // double linked list head pointer
virtual void set(int, int) = 0; //set function
virtual int get(int) = 0; //get function
};
class LRUCache : public Cache
{
private:
int count;
public:
LRUCache(int capacity)
{
cp = capacity;
tail = NULL;
head = NULL;
count = 0;
}
What is wrong with my code?? What should be the proper code implementation so as not to get any warnings??
The problem here is initialization order in your Node struct.
In C++ members are initialized in the order they are declared, regardless the order they are listed in the constructor initializer list.
Thus they are initialized in the order next, prev, value, key.
Listing them differently in the constructor can be misleading and thus the warning is telling you to list them there in the same order they are declared.
I have implemented some functions for a Stack in C++. I am unsure as to why I am getting a segmentation fault. Right now, I have 7 different files: node.h, node.cpp, LL.h, LL.cpp, Stack.h, Stack.cpp and main.cpp which I am using to test LL.cpp and Stack.cpp. If anyone could direct me to the error, I would really appreciate it. Here are the codes:
node.h :
// node.h
class node { // node class used in the LL (linked list) class
private:
node * next; // Pointer to next node of an LL
int data; // integer data stored in this node
public:
node(int x, node * n); // Constructor
~node(); // Destructor
void set_data(int x); // Change the data of this node
void set_next(node * n);// Change the next pointer of this node
int get_data(); // Access the data of this node
node * get_next(); // Access the next pointer of this node
};
LL.h :
// LL.h
#include "node.h"
// Linked list class, used in the Stack class
class LL {
private:
node * head; // pointer to first node
node * tail; // pointer to last node
public:
LL(); // Constructor
~LL(); // Destructor
void prepend(int value); // add a node to the beginning of the LL
int removeHead(); // remove the first node of the LL
void print(); // print the elements of the LL
node * get_head(); // access the pointer to the first node of the LL
};
Stack.h:
// Stack.h
#include "LL.h"
class Stack {
private:
LL * intlist;
public:
Stack(); // Constructor
~Stack(); // Destructor
void push(int value);
int pop();
int isEmpty();
void Sprint();
};
Stack.cpp:
// Stack.cpp
#include "Stack.h"
#include <stdio.h>
Stack::Stack() {
}
Stack::~Stack() {
}
int Stack::isEmpty() {
return ( (intlist->get_head()) ==NULL);
}
void Stack::push(int value) {
intlist->prepend(value);
}
int Stack::pop() {
if ( ! isEmpty() ) {
int result=intlist->removeHead();
return result;
}
return -1;
}
void Stack::Sprint() {
intlist->print();
}
And here is the main.cpp that I am using to test it:
// main.cpp
#include "Stack.h"
#include <stdio.h>
int main() {
LL a;
a.prepend(3);
a.prepend(4);
a.prepend(5);
a.print();
a.removeHead();
a.print();
Stack sta;
sta.pop();
sta.push(3);
sta.push(4);
sta.push(10);
sta.Sprint();
printf("Popping %d\n", sta.pop());
sta.Sprint();
sta.pop();
printf("Stack empty? %d\n", sta.isEmpty());
sta.pop();
printf("Stack empty? %d\n", sta.isEmpty());
return 0;
}
I have been trying to find what's causing the segmentation fault for a while. Any help appreciated
This program is crashing because your Stack class never initializes the Linked List pointer (LL * intlist), so when you check if it's empty it tries referencing garbage:
Stack.pop() => Stack.isEmpty() => intlist->isEmpty() => segfault
You could just make it a member instead of a pointer (recommended):
class Stack {
private:
LL intlist; // There's no need for it to be a pointer
public:
Stack(); // Constructor
~Stack(); // Destructor
void push(int value);
int pop();
int isEmpty();
void Sprint();
};
Alternatively, you could initialize it in the constructor and delete it in the destructor. You should really only do this when a member variable needs to be a pointer; otherwise you should just store it regularly.
Stack::Stack() : intlist(new LL()) {
}
Stack::~Stack() {
delete intlist;
}
Pointer intlist in Stack is never initialized, so attempting to dereference it caused your segfault (in this case, it was when sta.pop() was first called).
You could allocate memory for intlist in Stack's constructor (e.g. intlist = new LL;) and delete it when you're done (or use a smart pointer instead). But in this case that'll do more harm than good.
You're likely better off defining intlist as an object of type LL, not a pointer to it, in Stack:
class Stack {
private:
LL intlist;
...
};
Of course, don't forget to replace all arrow operators (->) with dot operators (.) when working with intlist.
I created a private static variable that keeps track of the number of elements in the linked list.
struct node
{
int data;
node *next;
};
class linkedList
{
private:
node *head,*tail;
static int listSize;
public:
linkedList()
{
head=NULL;
tail=NULL;
}
void insert(int n)
{
node *temp=new node;
temp->data=n;
temp->next=NULL;
if(head == NULL)
{
head=temp;
tail=temp;
}
else
{
tail->next=temp;
tail=temp;
}
linkedList::listSize+=1;
}
};
void main()
{
linkedList l;
l.insert(10);
l.insert(20);
}
The compiler throws an error when it reaches the line linkedList::listSize+=1;
error: ‘linkedList’ has not been declared.
Once your typos corrected (inser(20) instead of insert(20) and : instead of ; in linkedList(), your program almost compiles.
There is just one thing missing: you need to implement the listSize variable somewhere for example by putting int linkedList::listSize; before main:
...
int linkedList::listSize; /(/ <<< add this
void main()
{
linkedList l;
l.insert(10);
l.insert(20);
}
But why are you using a static variable for counting the elements of the list? You probably want listSize to be an ordinary (non static) class member, just as head and tail:
class linkedList
{
private:
node * head, *tail;
int listSize; // no static
public:
...
and drop the int linkedList::listSize; suggested before.
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set.
get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
set(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.
#include <iostream>
#include <map>
using namespace std;
struct node{
int val;
struct node* next;
struct node* prev;
};
class dlist{
public:
dlist(){}
dlist(int capacity){
cap=capacity;
}
void add(int value){
node* n=new node;
n->val=value;
if (size==0){
size++;
tail=n;
head=tail;
}
else {
if (size==cap){
node* buf=head;
head=head->next;
head->prev=NULL;
delete buf;
size--;
}
tail->next=n;
n->prev=tail;
tail=n;
size++;
}
}
int getVal(){
if (tail==NULL)
return -1;
return tail->val;
}
private:
int cap;
int size;
node* tail;
node* head;
};
class LRUCache{
public:
LRUCache(int capacity) {
cap=capacity;
}
int get(int key) {
if(cap!=0&&cache.find(key)!=cache.end())
return cache[key].getVal();
return -1;
}
void set(int key, int value) {
if (cap==0)
return;
if(cache.find(key)==cache.end()){
dlist d=dlist(cap);
cache.insert(make_pair(key,d));
}
cache[key].add(value);
}
private:
int cap;
map<int,dlist> cache;
};
int main()
{
LRUCache lru(3);
cout<<"asd";
lru.set(1,9);
lru.set(1,8);
lru.set(1,1);
lru.set(1,7);
lru.set(2,9);
cout<<lru.get(1)<<endl;
cout<<lru.get(2)<<endl;
cout<<lru.get(3)<<endl;
return 0;
}
so I used a map and a custom double linked list, it seems to working fine with if I add the cout line right after initializing LRU, but it will have seg fault if I don't, I and not very sure what should I do to manage the memory use of LRU(if this is the problem)
Also if there's any line that could be better written(aside from std namespace) please tell me, I would really appreciate that.
Your program exhibits undefined behavior since the member variables size, tail, and head of dlist are not initialized before being used.
Use
dlist() : dlist(0) {}
dlist(int capacity) : cap(capacity), size(0), tail(nullptr), head(nullptr) {}
That fixes the segmentation violation problem in my testing.
I recommend adding a constructor to node also:
struct node{
node(int v) : val(v), next(nullptr), prev(nullptr) {}
int val;
struct node* next;
struct node* prev;
};
and use
node* n=new node(value);
instead of
node* n=new node;
n->val=value;
Just started learning c++ for a class, I can't figure out what is wrong with this code! I'm making a stack class with a helper class nested inside it called node that acts as a linked list. The error I'm getting is on line 12 and is:
Stack.cpp: In destructor ‘Stack::~Stack()’:
Stack.cpp:12:24: error: request for member ‘getNext’ in ‘((Stack*)this)->Stack::node’, which is of non-class type ‘Stack::Node*’
Here's my code:
#include "Stack.h"
Stack:: Stack ()
{
height = 0;
node = 0;
}
Stack:: ~Stack()
{
while(node != 0){
Node *next = *node.getNext();
delete node;
node = next;
}
node = 0;
}
And Here's my header file:
using namespace std;
class Stack
{
private:
int height;
class Node{
private:
int data;
Node* next;
public:
void setData(int x){
data = x;
}
void setNext(Node* x){
next = x;
}
int getData(){
return data;
}
Node* getNext(){
return next;
}
};
Node* node;
public:
Stack();
~Stack();
void push(int x);
int pop();
int peek();
int getHeight();
bool isEmpty();
};
Node *next = *node.getNext();
should be
Node *next = (*node).getNext();
Since . operator has higher precedence than * deference operator.
You can also use:
Node *next = node->getNext();