I am trying to directly access integer from a pointer class, by overloading * operator, but it seems VC++ 10 is not allowing it. Kindly help:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
int MAX7 = 10;
struct node{
int value;
node *next;
};
struct node *head = NULL;
struct node *current = NULL;
int count = 0;
class SmartPointer{
public:
SmartPointer(){
}
int push(int i){
if(count == MAX7) return 0;
if(head == NULL){
head = new node();
current = head;
head -> next = NULL;
head -> value = i;
count = 1;
}
else{
struct node *ptr = head;
while(ptr->next != NULL) ptr = ptr->next;
ptr->next = new node;
ptr = ptr->next;
ptr->next = NULL;
ptr->value = i;
count++;
}
return 1;
}
void Display(){
node *ptr = head;
while(ptr != NULL){
cout << ptr->value << "(" << ptr << ")";
if( ptr == current )
cout << "*";
cout << ", ";
ptr = ptr->next;
}
}
int operator *(){
if(current == NULL) return -1;
struct node *ptr = current;
return ptr->value;
}
};
int main(){
SmartPointer *sp;
sp = new SmartPointer();
sp->push(99);
for(int i=100; i<120; i++){
if(sp->push(i))
cout << "\nPushing ("<<i<<"): Successful!";
else
cout << "\nPushing ("<<i<<"): Failed!";
}
cout << "\n";
sp->Display();
int i = *sp;
getch();
return 0;
}
Error#
1>test7.cpp(71): error C2440: 'initializing' : cannot convert from 'SmartPointer' to 'int'
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
sp is not a smart pointer - it's a plain old dumb pointer to SmartPointer class. *sp uses built-in dereference operator, producing an lvalue of SmartPointer type. It does not call SmartPointer::operator*() - for that, you need to write **sp (two stars).
It's not at all clear why you want to allocate SmartPointer instance on the heap. That's an unusual thing to want to do (also too, you leak it). I'm pretty sure you would be better off with
SmartPointer sp;
sp.push(99);
and so on.
short answer:
int i = **sp;
You should not allocate objects with new. Your code looks like java. In C++, you must delete everything you allocate with new. In C++ you can write:
SmartPointer sp;
sp.push(99);
int i = *sp;
Related
I've been working on a program to implement a binary search tree, but using recursion, I have to call the root pointer in the main function. I get the error that 'root was not declared in this scope', although I've declared it inside the bstree class in public. I've been having a really hard time for the past couple of days coming back to this problem and searching all over the internet, so some help would really be appreciated. My code is below (i've removed some functions)
#include <iostream>
using namespace std;
struct Node{
int data;
Node* left;
Node* right;
};
class Bstree{
public:
** Node* root = nullptr;
**
Bstree(){
root = new Node();
}
void insert(Node* root, int x){
if (root==nullptr) {
Node* n = new Node;
n->data = x;
n->right = n->left = nullptr;
} else if (x<root->data) {
insert(root->left, x);
} else {
insert(root->right, x);
}
}
void inorder(Node* root){
if (root==NULL) return;
inorder(root->left);
cout << root->data << " ";
inorder(root->right);
}
void postorder(Node* root){
if (root==NULL) return;
postorder(root->left);
postorder(root->right);
cout << root->data << " ";
}
};
int main(){
Bstree BST;
int N; cin >> N;
for (int i=0;i<N;i++){
int x; cin >> x;
BST.insert(root, x);
}
BST.inorder(root);
BST.postorder(root);
}
I tried to make all recursive functions itirative, but itirative traversal functions are way more complicated than recursive. I tried writing *root instead of root when calling the functions, but I got the same error. Isn't root a global variable anyways since I declared it in a public class?
root is a member of the Bstree class, not a variable that is available in main. In main you could access it with BST.root, however, I feel that the main program has no business with that member. It should be the class that deals with those details, while the main program should just rely on the methods and not have to know about the root member.
So, I would suggest defining public methods on your class that do not take a root parameter. The class knows what the root is, so there's no need for the caller to pass it. However, the recursive calls do need that argument, but those recursive functions could be private methods.
Another issue is that your constructor creates a dummy node and assigns it to the root. This is not good. An empty tree has no node, so you should just leave the root to its initial nullptr value.
Here is an update of your code that fixes these problems:
#include <iostream>
using namespace std;
struct Node{
int data;
Node* left;
Node* right;
};
class Bstree{
private:
Node* root = nullptr;
void insert(Node* &root, int x){
if (root==nullptr) {
root = new Node;
root->data = x;
root->right = root->left = nullptr;
} else if (x<root->data) {
insert(root->left, x);
} else {
insert(root->right, x);
}
}
void inorder(Node* root){
if (root==NULL) return;
inorder(root->left);
cout << root->data << " ";
inorder(root->right);
}
void postorder(Node* root){
if (root==NULL) return;
postorder(root->left);
postorder(root->right);
cout << root->data << " ";
}
public:
// Define the public methods without root argument.
void insert(int x){
// But use a recursive private method that does take that argument
// and pass that argument by reference
insert(root, x);
}
void inorder() {
inorder(root);
}
void postorder() {
postorder(root);
}
};
int main(){
Bstree BST;
int N;
cin >> N;
for (int i = 0; i < N; i++) {
int x;
cin >> x;
BST.insert(x);
}
BST.inorder();
cout << "\n";
BST.postorder();
cout << "\n";
}
I am going to create a single linked list and construct a function (Locate()) that returns the address of the element.But in the end, I didn't see the result of this function. I tried it. This function should be run, but the result is different from what I expected.
use vs2019 on WIndows10,a student:)
#include<iostream>
using namespace std;
struct Node { //Node
int data;
Node* link;
Node(int item, Node* l = NULL)
{
data = item;
link = l;
}
Node(Node* l = NULL)
{
data = 0;
link = l;
}
};
class Link :public Node { //Link
private:
Node* first;
public:
Link(Node* l = NULL)
{
first = l;
}
Link(int d, Node* l = NULL)
{
first = new Node(d);
}
Node* Locate(int i);
};
Node* Link::Locate(int i) //Locate()
{
if (i < 0)
{
cerr << "wrong operation when locating" << endl;
exit(1);
}
int count = 0;
Node* current = first;
while (count < i && current->link != NULL)
{
current = current->link;
count++;
}
return current;
}
int main()
{
Link a;
Node* b = new Node(1);
Node* c = new Node(2);
a.link = b;
b->link = c;
cout << a.data << ' ' << b->data << ' '<<c->data<<endl;
cout << a.Locate(1) << endl;
return 0;
}
Will not output the result of this function 'Locate()' being called
Locate() accesses first->link. At that time, first is a null pointer. Whereupon your program exhibits undefined behavior; in practice, it most likely crashes.
When I re-modify the List constructor, its(Locate()) output is normal and the expected result is obtained.
The modified constructors are as follows:
Link()
{
first = new Node;
}
Link(int d)
{
first = new Node(d);
}
Node* Locate(int i);
I've implemented a method to find a value from a 'Stack'. I just want to know that are there any logical errors or any kind of errors in this code?
Thanks.
bool about::findData(char key)
{
if(top==-1)
cout<<"Stack is Empty"<<endl;
else
{
for(int x=0; x<maxSize-1; x++)
{
if(stackArray[x]==key)
return stackArray[x];
}
}
}
I don't really know what you want to do / ask. From a logical point of view this program will work.
But you got some hops and jumps in there. I will start with a working example and point out the differences.
Note that I won't address the stack logic in itself. It seems like you did start out with a stack like thing, but got driven quite away from it?
You have a (top == -1) query in there, but never ever declared top / assigned a value to it. I assumed that you meant the size of the array (not that this is probably not the best way to calculate the array size, especially as C++ has a vector container anyways).
You iterate over maxSize elements, yet didn't declare maxSize anywhere. This also assumes that your stack is of fixed size and all elements are initiated with a sane value. I am just iterating over the size of the current array right now.
You return the value return stackArray[x];, yet declared your function to have a bool return value - this does no harm in itself, but I went for returning true and false to adhere to the return value.
Try the code online.
#include <iostream>
using namespace std;
int maxSize = 10;
char stackArray[] = {'b', 'a', 'c', 'd'};
//char stackArray[] = {};
bool findData(char key)
{
int top = (sizeof(stackArray)/sizeof(*stackArray));
cout << "Size of array is: " << top << endl;
if(top <= 0)
cout<<"Stack is Empty"<<endl;
else
{
for(int x=0; x<top; x++)
{
if(stackArray[x]==key)
return true;
}
return false;
}
}
int main() {
if(findData('a')) {
cout << "We found the value!" << endl;
} else {
cout << "We didn't find the value!" << endl;
}
}
EDIT
And as I couldn't resist I jump started with an array based stack architecture from here and implemented our beloved findValue within this stack.
#include <iostream>
#include <string>
using namespace std;
class Stack {
private:
int top;
int capacity;
int *storage;
public:
Stack(int capacity) {
if (capacity <= 0)
throw string("Stack's capacity must be positive");
storage = new int[capacity];
this->capacity = capacity;
top = -1;
}
void push(int value) {
if (top == capacity)
throw string("Stack's underlying storage is overflow");
top++;
storage[top] = value;
}
int peek() {
if (top == -1)
throw string("Stack is empty");
return storage[top];
}
void pop() {
if (top == -1)
throw string("Stack is empty");
top--;
}
/* Our findValue function. */
bool findValue(int key) {
/* Now the usage of top makes perfect sense,
the counter variable always contains the amount
of stored elements. */
if (top == -1) {
throw string("Stack is empty");
}
/* We traverse all elements of our storage. */
for (int i = 0; i < top; i++) {
if(storage[i] == key) {
return true;
}
}
return false;
}
bool isEmpty() {
return (top == -1);
}
~Stack() {
delete[] storage;
}
};
int main() {
/* Init the new stack. */
Stack* stack = new Stack(10);
/* Push some elements for more fun. */
stack->push('a');
stack->push('b');
stack->push('c');
stack->push('d');
stack->push('e');
stack->push('f');
/* Show charcode of last pushed element. */
cout << stack->peek() << endl;
/* Find 'e'. */
if (stack->findValue('e')) {
cout << "We found the value" << endl;
}
/* Try and not find 'g'. */
if (!(stack->findValue('g'))) {
cout << "We didn't find the value" << endl;
}
delete stack;
return 0;
}
I have an assignment and it's to build a queue linked list.
Our professor gave us the skeleton and told us to use his main.
I wrote my functions and everything compiled right but when I ran it, I got this error.
Don't know what to do from here.
Source Code:
#include<iostream>
using namespace std;
template<class ItemType>
struct NodeType
{
ItemType info;
NodeType* next;
};
template<class ItemType>
class Queue
{
private:
int size;
NodeType<ItemType>* front; // It points to the front of a singly-linked list
NodeType<ItemType>* rear; // It points to the end of a singly-linked list
public:
Queue(); // default constructor: Queue is created and empty
Queue(const Queue<ItemType> &x); // copy constructor: implicitly called
// for a deep copy
void MakeEmpty(); // Queue is made empty; you should deallocate all
// the nodes of the linked list
bool IsEmpty( ); // test if the queue is empty
bool IsFull( ); // test if the queue is full; assume MAXITEM=5
int length( ); // return the number of elements in the queue
void Print( ); // print the value of all elements in the queue in the sequence
// from the front to rear
void Enqueue(ItemType x); // insert x to the rear of the queue
// Precondition: the queue is not full
void Dequeue(ItemType &x); // delete the element from the front of the queue
// Precondition: the queue is not empty
~Queue(); // Destructor: memory for the dynamic array needs to be deallocated
};
template<class ItemType>
Queue<ItemType>::Queue()
{
size = 0;
front = NULL;
rear = NULL;
}
template<class ItemType>
Queue<ItemType>::Queue(const Queue<ItemType> &x)
{
NodeType<ItemType>* ptr1 ;
NodeType<ItemType>* ptr2 ;
if ( x.front == NULL )
{
front = NULL ;
}
else // allocate memory for first node
{
front = new NodeType<ItemType> ;
front->info = x.front->info ;
ptr1 = x.front->next ;
ptr2 = front ;
while ( ptr1 != NULL ) // deep copy other nodes
{
ptr2->next = new NodeType<ItemType> ;
ptr2 = ptr2->next ;
ptr2->info = ptr1->info ;
ptr1 = ptr1->next ;
}
ptr2->next = NULL;
rear = ptr2;
}
}
template<class ItemType>
void Queue<ItemType>::MakeEmpty()
{
NodeType<ItemType>* tempPtr;
while(front != NULL)
{
tempPtr = front;
front = front->next;
delete tempPtr;
}
rear=NULL;
}
template<class ItemType>
bool Queue<ItemType>::IsEmpty()
{
return (size == 0);
}
template<class ItemType>
bool Queue<ItemType>::IsFull()
{
return (size >= 5);
}
template<class ItemType>
int Queue<ItemType>::length()
{
return size;
}
template<class ItemType>
void Queue<ItemType>::Enqueue(ItemType x)
{
NodeType<ItemType>* newNode;
newNode = new NodeType<ItemType>;
newNode->info = x;
newNode->next = NULL;
if(rear == NULL)
{
front = newNode;
}
else
{
rear->next = newNode;
rear = newNode;
}
size++;
}
template<class ItemType>
void Queue<ItemType>::Dequeue(ItemType &x)
{
NodeType<ItemType>* tempPtr;
if(!IsEmpty())
{
tempPtr = front;
x = front->info;
front = front->next;
if(front == NULL)
{
rear = NULL;
}
delete tempPtr;
}
size--;
}
template<class ItemType>
void Queue<ItemType>::Print()
{
NodeType<ItemType> *temp;
temp = rear;
while(temp != NULL)
{
cout<<temp->info<<endl;
temp = temp->next;
}
}
template<class ItemType>
Queue<ItemType>::~Queue()
{
MakeEmpty();
}
int main()
{
Queue<int>IntQueue;
int x;
IntQueue.MakeEmpty();
IntQueue.Dequeue(x);
IntQueue.Enqueue(10);
IntQueue.Enqueue(20);
IntQueue.Enqueue(30);
IntQueue.Enqueue(40);
cout << "int length 3 = " << IntQueue.length() << endl;
IntQueue.Dequeue(x);
cout << "int length 4 = " << IntQueue.length() << endl;
cout << "The int queue contains: " << endl;
IntQueue.Print();
if(IntQueue.IsFull() == false)
cout << "The int queue is not full !" << endl;
else
cout << "The int queue is full !" << endl;
Queue<float>FloatQueue;
float y;
FloatQueue.MakeEmpty();
FloatQueue.Dequeue(y);
FloatQueue.Enqueue(7.1);
cout << "float length 3 = " << FloatQueue.length() << endl;
FloatQueue.Enqueue(2.3);
cout << "float length 4 = " << FloatQueue.length() << endl;
FloatQueue.Enqueue(3.1);
FloatQueue.Dequeue(y);
cout << "The float queue contains: " << endl;
FloatQueue.Print();
Queue<float> FloatQueue2 = FloatQueue;
cout << "The float queue 2 contains: " << endl;
FloatQueue2.Print();
FloatQueue.MakeEmpty();
cout << "The float queue 3 contains: " << endl;
FloatQueue2.Print();
system("pause");
return 0;
}
The problem I'm having is obviously with the print function.
Any help is appreciated.
Inside your copy constructor, you aren't setting rear to anything when x.front == NULL. This sets temp to an invalid value inside Print, causing you both to loop when you shouldn't and dereference an invalid pointer.
The following program goes into a deadlock. Can anyone please tell me why?
#include<cstdlib>
#include<windows.h>
#include<iostream>
using namespace std;
class CircularQueue
{
public:
CircularQueue(int s)
{
size = s;
array = (int*)malloc(sizeof(int) * size);
head = tail = -1;
InitializeCriticalSection(&critical_section);
}
CircularQueue(void)
{
size = default_size;
array = (int*)malloc(sizeof(int) * size);
head = tail = -1;
InitializeCriticalSection(&critical_section);
}
void initialize(int s)
{
EnterCriticalSection(&critical_section);
size = s;
array = (int*)realloc(array, sizeof(int) * size);
head = tail = -1;
LeaveCriticalSection(&critical_section);
}
void enqueue(int n)
{
EnterCriticalSection(&critical_section);
tail = (tail + 1) % size;
array[tail] = n;
LeaveCriticalSection(&critical_section);
}
int dequeue(void)
{
EnterCriticalSection(&critical_section);
head = (head + 1) % size;
return array[head];
LeaveCriticalSection(&critical_section);
}
private:
int *array;
int size;
int head, tail;
CRITICAL_SECTION critical_section;
bool initialized;
static const int default_size = 10;
};
DWORD WINAPI thread1(LPVOID param)
{
CircularQueue* cqueue = (CircularQueue*)param;
cqueue->enqueue(2);
cout << cqueue->dequeue() << endl;
return 0;
}
DWORD WINAPI thread2(LPVOID param)
{
CircularQueue* cqueue = (CircularQueue*)param;
cqueue->enqueue(3);
cout << cqueue->dequeue() << endl;
return 0;
}
int main(void)
{
HANDLE thread1_handle;
HANDLE thread2_handle;
CircularQueue cqueue;
HANDLE array[2];
thread1_handle = CreateThread(NULL, 0, thread1, &cqueue, 0, NULL);
thread2_handle = CreateThread(NULL, 0, thread2, &cqueue, 0, NULL);
array[0] = thread1_handle;
array[1] = thread2_handle;
WaitForMultipleObjects(1, array, TRUE, INFINITE);
CloseHandle(thread1_handle);
CloseHandle(thread2_handle);
printf("end\n");
return 0;
}
In dequeue(), you have a return statement before the LeaveCriticalSection() call. If you had compiler warnings turned up higher, it would probably have told you about this!