C++ property on class seems to be reinitialized - c++

In the class Element, i have a property called size with default value 0.
When I call the insertElement on main() the line that calls size++ works fine but, in the next line when function shiftElementsToRight(i); are called, the size element are restarted to 0.
Why this happens? I'm declaring in wrong way my Element class?
Using g++ 9.2.1 on Ubuntu Linux
#include<iostream>
using namespace std;
int const ARRAY_MAX = 100;
class Element {
public:
int elements[ARRAY_MAX] = {};
int size = 0;
void shiftElementsToRight(int pos) {
int temp = elements[pos+1];
for (int i=ARRAY_MAX-1; i>=pos; i--) {
elements[i+1] = elements[i];
}
elements[pos] = NULL;
}
void shiftElementsToLeft(int pos) {
int temp = elements[pos];
int i = ARRAY_MAX;
for (int i=pos; i<ARRAY_MAX-1; i++) {
elements[i-1] = elements[i];
}
}
void insertElement(int value) {
int i = 0;
size++;
while ((i<ARRAY_MAX) && (elements[i] != NULL)) {
if (elements[i]>value) {
break;
}
i++;
}
shiftElementsToRight(i);
elements[i] = value;
}
int deleteElement(int value) {
int pos = binarySearch(value);
if (pos!=-1) {
shiftElementsToLeft(pos+1);
}
size--;
return pos;
}
int binarySearch(int value) {
int left = 0;
int right = size;
cout << "Begin" << endl;
while (left<right) {
int middle = left + (right -left) / 2;
cout << "L: " << left << " R: " << right << endl;
if (elements[middle] == value) {
return middle;
}
if (elements[middle]>value) {
right = middle-1;
}
if (elements[middle]<value) {
left = middle+1;
}
}
return -1;
}
};
int main() {
Element *element = new Element();
element->insertElement(3);
element->insertElement(2);
element->insertElement(5);
element->insertElement(6);
element->insertElement(4);
element->deleteElement(3);
return 0;
}

In
for (int i=ARRAY_MAX-1; i>=pos; i--) {
elements[i+1] = elements[i];
}
Your first access to elements is at position ARRAY_MAX - 1 + 1. You're accessing elements[ARRAY_MAX], which is outside the bounds of this array and (likely) points to size.

Related

infix to postfix equations using stack

I am trying to make program that get infix to postfix but when I entered +- in the infix equation
the output should be +- but I find that the output is ++ and if infix is -+ the output is --
it have been a week since I started to solve that problem
#include <iostream>
#include <string>
using namespace std;
//classes
class arr
{
private:
char *items;
int size;
int length;
public:
//default constructor
arr()
{
items = new char[100];
size = 100;
length = 0;
}
//constructor with parameters
arr(int arraySize)
{
items = new char[arraySize];
size = arraySize;
length = 0;
}
//check if array is empty
bool is_empty()
{
return length == 0 ? true : false;
}
//check if array full
bool is_full()
{
return length >= size - 1 ? true : false;
}
//returns array length
int getLength()
{
return length;
}
//return array size
int getSize()
{
return size;
}
//get array address
char *getAddress()
{
return &items[0];
}
//fill number of items in array based on elementNum
void fill(int elementNum)
{
char ch;
cout << "Enter characters you want to add\n";
if (elementNum > size - 1)
{
cout << "can't use elements number largger than " << size - 1;
return;
}
for (int i = 0; i < elementNum; i++)
{
cin >> ch;
insert(i, ch);
}
}
//display all elements in the array
void display()
{
if (is_empty())
{
cout << "there are no data /n";
return;
}
cout << "Array items are :\n";
for (int i = 0; i < length; i++)
{
cout << items[i] << "\t";
}
cout << endl;
}
void append(char ch)
{
insert(length, ch);
}
void insert(int index, char newItem)
{
if (is_full() || length<index || length + 1 == size)
{
cout << "\nSorry array is full\ncan't append letter more\n";
return;
}
else {
for (int i = length; i >= index; i--)
{
items[i + 1] = items[i];
}
items[index] = newItem;
length++;
}
}
int search(char ch)
{
if (!is_empty())
for (int i = 1; i <= length; i++)
{
if (items[i] == ch)
return i;
}
return 0;
}
void del(int index)
{
if (is_empty() || length<index) {
cout << "sorry can't delete item which is doesn't exist";
return;
}
for (int i = index; i < length; i++)
{
items[i] = items[i + 1];
}
length--;
}
void changeSize(int newSize)
{
if (newSize <= length - 1)
{
cout << "can't change size because the new size is small";
return;
}
char *tempItems = new char[newSize];
size = newSize;
for (int i = 0; i < length; i++)
{
tempItems[i] = items[i];
}
items = tempItems;
tempItems = NULL;
}
//merge two arrays
void merge(arr a)
{
this->size = this->size + a.getSize();
for (int i = 0; i < a.getLength(); i++)
{
items[i + length] = a.getAddress()[i];
}
length = this->length + a.getLength();
}
};
class stackUsingArray {
private:
int top;
arr a;
public:
stackUsingArray()
{
top = -1;
}
stackUsingArray(int stackSize)
{
a.changeSize(stackSize);
top = -1;
}
bool is_empty()
{
return(top == -1);
}
bool is_full()
{
return(a.is_full());
}
void push(char ch)
{
top++;
a.append(ch);
}
char pop()
{
if (is_empty())
{
cout << "sorry the stack is empty";
}
else
return a.getAddress()[top--];
}
int peekTop() {
return top;
}
void display()
{
//first way of display
for (int i = top; i >= 0; i--)
{
cout << a.getAddress()[i];
}
//second way of display
//stackUsingArray c;
//char ch;
//for (int i = top; i >= 0; i--)
// c.push(this->pop());
//for (int i = c.peekTop(); i >= 0; i--)
//{
// ch=c.pop();
// this->push(ch);
// cout << ch;
//}
}
int search(char ch)
{
for (int i = top; i >= 0; i--)
{
if (a.getAddress()[i] == ch)
return i;
}
return -1;
}
char topDisplay()
{
return a.getAddress()[top];
}
};
class stackUsingLinkedList {};
//functions
string infixToPostfix(string infix);
short prec(char ch);
int main()
{
//infix and postfix
stackUsingArray c;
cout<<infixToPostfix("x+y-z");
system("pause");
return 0;
}
string infixToPostfix(string infix)
{
string postfix = "";
stackUsingArray sta;
char ch;
char test;
for (int i = 0; i < infix.length(); i++)
{
switch (prec(infix[i]))
{
case 0:
postfix.append(1, infix[i]);
break;
case 1:
sta.push(infix[i]);
break;
//case 2:
// ch = sta.pop();
// while (ch != '(')
// {
// postfix.append(1, ch);
// ch = sta.pop();
// }
// break;
case 3:
// if (sta.is_empty())
// {
// goto k270;
// }
// ch = sta.pop();
// while (prec(ch) > 3)
// {
// postfix.append(1, ch);
// if (sta.is_empty()) {
// //sta.push(infix[i]);
// goto k270;
// }
// ch = sta.pop();
// }
// sta.push(ch);
//k270:
// sta.push(infix[i]);
test = sta.topDisplay();
if (sta.is_empty())
{
sta.push(infix[i]);
test = sta.topDisplay();
}
else
{
ch = sta.pop();
test = sta.topDisplay();
if (prec(ch) >= 3)
{
postfix += ch;
}
sta.push(infix[i]);
}
}
}
while (!sta.is_empty())
{
postfix.append(1, sta.pop());
}
return postfix;
}
short prec(char ch)
{
if (ch == '(')
return 1;
if (ch == ')')
return 2;
if (ch == '+')
return 3;
if (ch == '-')
return 3;
if (ch == '*')
return 4;
if (ch == '/')
return 4;
return 0;
}
thanks to #IgorTandetnik I figured out that I should del last item from the array when I pop from stack

Is there a command to check if objects in my dynamic array are dynamic or static?

I made a dynamic array with template. The problem is that when I don't keep there pointers (for example: Tab<string> da;) my destructor doesn't have to clear it and throws error caused by delete arr[i];. My question is if I can put some if condition(in which I would put clear() method) which would tell me if my array keeps pointers. In the simplest way I can use clear() in main when I keeps there pointers, but my teacher wants me to make it like I wrote above.
I tried using is_pointer, but it doesn't work or I use it wrong.
Any suggestions?
#ifndef TABLICA_H
#define TABLICA_H
#include <iostream>
#include <type_traits>
using namespace std;
template<class T>
class Tab
{
public:
int size = 0;
int max_size = 1;
T* arr;
bool isDynamic = false;
Tab()
{
arr = new T[max_size];
}
~Tab()
{
clear();
delete[] arr;
}
void check_size()
{
if (size == max_size)
{
max_size = max_size * 2;
T* arr2 = new T[max_size];
for (int i = 0; i < size; i++)
{
arr2[i] = arr[i];
}
delete[] arr;
arr = arr2;
}
}
void push_back(const T& value)
{
check_size();
arr[size] = value;
size++;
}
T return_by_index(int index)
{
if (index<0 || index > size)
{
return NULL;
}
return arr[index];
}
bool replace(int index, const T& value)
{
if (index<0 || index > size)
{
return false;
}
arr[index] = value;
return true;
}
void print(int number)
{
cout << "Rozmiar obecny: " << size << endl;
cout << "Rozmiar maksymalny: " << max_size << endl;
cout << "Adres tablicy: " << arr << endl;
cout << "Kilka poczatkowych elementow tablicy " << "(" << number << ")" << endl;
for (int i = 0; i < number; i++)
{
cout << *arr[i] << endl;
}
}
void clear()
{
for (int i = 0; i < size; i++)
{
delete arr[i];
}
}
};
#endif
//Source:
#include <iostream>
struct object
{
int field1;
char field2;
object()
{
field1 = rand() % 10001;
field2 = rand() % 26 + 'A';
}
};
ostream& operator<<(ostream& out, const object& o)
{
return out << o.field1 << " " << o.field2;
}
int main()
{
Tab < object* >* da = new Tab < object* >();
delete da;
system("PAUSE");
return 0;

How to initialize the dynamic array of struct in the constructor?

This is a Stack class based on a dynamic array of struct for Depth First Search (DFS). The program is not able to run whenever it encounters the function, push(), which shows that the array is not successfully initialized in the constructor.
I have tried to look for the error and even changing the dynamic array of struct into parallel arrays but it still does not work. I apologize if the problem seems to be too simple to be solved as I do not have a strong foundation in C++.
#include <iostream>
#include <iomanip>
#ifndef HEADER_H
#define HEADER_H
using namespace std;
struct Value
{
int row; // row number of position
int col; // column number of position
//operator int() const { return row; }
};
class ArrayStack
{
public:
int top;
Value* array;
ArrayStack();
bool isEmpty();
bool isFull();
void push(int r, int c);
void pop();
int poprowvalue(int value);
int popcolvalue(int value);
int peekrow(int pos);
int peekcol(int pos);
int count();
void change(int pos, int value1, int value2);
void display();
void resize();
private:
int size;
};
ArrayStack::ArrayStack()
{
//Initialize all variablies
top = -1;
size = 10;
Value * array = new Value[size];
for (int i = 0; i < size; i++)
{
array[i].row = 0;
array[i].col = 0;
}
}
bool ArrayStack::isEmpty()
{
if (top == -1)
return true;
else
return false;
}
bool ArrayStack::isFull()
{
if (top == size - 1)
return true;
else
return false;
}
void ArrayStack::resize()
{
if (isFull())
size *= 2;
else if (top == size / 4)
size /= 2;
}
void ArrayStack::push(int r, int c)
{
if (isEmpty() == false)
resize();
array[top + 1].row = r;
array[top + 1].col = c;
top++;
}
void ArrayStack::pop()
{
int value;
if (isEmpty())
{
cout << "Stack underflow" << endl;
}
else
{
poprowvalue(array[top].row);
popcolvalue(array[top].col);
array[top].row = 0;
array[top].col = 0;
top--;
}
}
int ArrayStack::poprowvalue(int v)
{
return v;
}
int ArrayStack::popcolvalue(int v)
{
return v;
}
int ArrayStack::peekrow(int pos)
{
if (isEmpty())
cout << "Stack underflow" << endl;
else
return array[pos].row;
}
int ArrayStack::peekcol(int pos)
{
if (isEmpty())
cout << "Stack underflow" << endl;
else
return array[pos].col;
}
int ArrayStack::count()
{
return (top + 1);
}
void ArrayStack::change(int pos, int value1, int value2)
{
if (isEmpty())
cout << "Stack underflow" << endl;
else
{
array[pos].row = value1;
array[pos].col = value2;
}
}
void ArrayStack::display()
{
for (int i = size - 1; i > -1; i--)
{
cout << array[i].row << " " << array[i].col << endl;
}
}
#endif
I expect it to run well but an exception is always thrown on line 80, which is as follows:
Exception thrown at 0x00007FF6A160487C in Assignment1.exe: 0xC0000005: Access violation writing location 0x0000000000000000.
The problem is this line right here:
Value * array = new Value[size];
This declares a new array variable. You are allocating that array instead, and not your member variable array.
The answer is simple, just change it to this instead:
array = new Value[size];

Huffman Encoding priority queue

I'm working on an assignment where I should write an encoding and decoding application for the Huffman algorithm, based on a priority queue. We have to read a file, count the frequencies of the letters and then start the algorithm. I have the following problem:
My counting function works fine but it stores the frequency of every letter in an array - even if it's zero. But if I want to use that array to build my min heap I get major problems because of the zeros. Therefore I need to find a way to 'eliminate' them. I can't just skip them because then the min heap algorithm doesn't work anymore (wrong neighbours). So I wanted to transfer all non-zero entries in a vector and use the vector instead of the array. But there I always get an error that tells me that there's a problem with the vector size. I don't really know how to deal with that problem. (My min heap still uses the array because I can't even transfer the entries in a vector).
(Please ignore the main I was just trying stuff there!)
using namespace std;
struct huffman_node
{ char data;
int frequency;
bool vector;
huffman_node *left;
huffman_node *right;
};
void swap_huffman_nodes(huffman_node &a, huffman_node &b)
{ char store_data = a.data;
int store_frequency = a.frequency;
a.data = b.data;
a.frequency=b.frequency;
b.data = store_data;
b.frequency = store_frequency;
huffman_node *store_left = a.left;
huffman_node *store_right= a.right;
a.left = b.left;
a.right = b.right;
b.left = store_left;
b.right = store_right;
}
void print_node (huffman_node a)
{ cout << a.data << a.frequency << endl;
}
string line;
huffman_node Table[52];
vector <huffman_node> non_zero;
void build_table()
{ for (int i=1; i<27; i++)
{ Table[i].data = (char) (i+64);
Table[i].left = NULL;
Table[i].right = NULL;
}
for (int i=27; i<53; i++)
{ Table[i].data = (char) (i+70);
Table[i].left = NULL;
Table[i].right = NULL;
}
}
int counter =0;
void count(){
ifstream yourfile ("example.txt");
if (yourfile.is_open())
{
while ( getline (yourfile,line) )
{
/*cout << line << '\n'; */
unsigned long z=line.length();
int i=0;
while ( i < z)
{ /* cout << line[i] << endl; */
for (int j=65; j<91; j++)
{ if ((int) line[i] == j)
{ int k=-64+j;
Table[k].frequency++;
}
}
for (int j=97; j<123; j++)
{ if ((int) line[i] == j)
{ int k=-70+j;
Table[k].frequency++;
}
}
i++;
}
}
for (int i=1; i<53; i++)
{ if (Table[i].frequency!=0)
{ non_zero.push_back(Table[i]);
counter ++;
}
}
yourfile.close();
}
else cout << "Unable to open file";
}
class heap{
public:
void buildheap()
{
for (int i=1; i<53; i++)
{reheap(i);
};
}
void reheap(int new_index)
{ int parent_index = new_index/2;
while (parent_index > 0 && Table[parent_index].frequency > Table[new_index].frequency)
{ swap_huffman_nodes(Table[parent_index], Table[new_index]);
parent_index=parent_index/2;
new_index=new_index/2;
}
};
void delete_root()
{ int non_null_entries=0;
for (int i=1; i<53; i++)
{ if (Table[i].frequency!=-1) {non_null_entries++;};
}
swap_huffman_nodes(Table[1],Table[non_null_entries]);
Table[non_null_entries].frequency=-1;
non_null_entries--;
rebuild_heap_root_deletion(1, non_null_entries);
}
void rebuild_heap_root_deletion(int new_root,int non_null_entries){
int n;
if (2 * new_root > non_null_entries){
return;
}
if (2 * new_root + 1 <= non_null_entries
&& Table[2*new_root+1].frequency < Table[2*new_root].frequency){
n = 2 * new_root + 1;
} else {
n = 2 * new_root;
}
if (Table[new_root].frequency > Table[n].frequency){
swap_huffman_nodes(Table[new_root], Table[n]);
rebuild_heap_root_deletion(n, non_null_entries);
}
}
void add_element(huffman_node new_heap_element)
{ for (int i=52; i>0;i-- )
{ if (Table[i].frequency==-1 && Table[i-1].frequency!=-1)
{ Table[i]=new_heap_element;
reheap(i);
break;
}
}
}
void print_Table()
{
for (int i=1; i<53; i++)
{ /*if (Table[i].frequency != -1) */
cout << Table[i].frequency << " , " << Table[i].data << endl;
}
}
bool empty_heap() // a heap is empty here if there are only "invalid huffman nodes" in it except the first one that contains all information.
{ for (int i=2; i < 53; i++)
{ if (Table[i].frequency!=-1)
{ return false;}
}
return true;
}
};
int main(){
ofstream myfile ("example.txt");
if (myfile.is_open())
{
myfile << "Flori ist ein Koala.";
myfile << "";
myfile.close();
}
else cout << "Unable to open file";
build_table();
count();
heap allan;
cout << "\n";
allan.buildheap();
allan.print_Table();
int i=0;
/*while(i<500)
{
huffman_node base_1 = Table[1];
allan.delete_root();
huffman_node base_2 = Table[1];
allan.delete_root();
huffman_node parent;
parent.data = '/';
parent.frequency = base_1.frequency + base_2.frequency;
parent.left = &base_1;
parent.right = &base_2;
allan.add_element(parent);
i++;
}
return 0;
}

Using object of class as an parametr in method

I have method of class Stack, which compares 2 objects of this class:
bool comparison(T &stack) {
if (size == stack.size)
for (int i = 0; i < size; i++) {
if (!this->stackPr[i].comparison(stack.stackPr[i]))
return false;
}
else
return false;
return true;
}
and uses the method of class Time:
bool comparison(Time &time) {
if ((this->hours == time.hours) && (this->minutes == time.minutes) && (this->seconds == time.seconds))
return true;
return false;
When I try to use this comman in main:
bool temp = stack3.comparison(stack4);
MVS underlines |stack4| and shows me the error:
a reference of type "Time &"(non-const qualified) cannot be initialized with a value of type Stack<Time>
How could I handle this problem?
Thanks for your answers :)
There is class Stack:
class Stack {
private:
T *stackPr;
int size;
int top;
public:
//----------------CONSTRUCTORS-----------------
Stack(int n) {
if (n > 0)
size = n;
else
size = 10;
stackPr = new T[size];
top = -1;
}
Stack() {
size = 10;
stackPr = new T[size];
top = -1;
}
Stack(Stack &stack) {
stackPr = new T[stack.size];
size = stack.size;
top = stack.top;
for (int i = 0; i < size; i++)
stackPr[i] = stack.stackPr[i];
}
Stack(T *objs, int sizeMass) {
size = sizeMass;
stackPr = new T[size];
for (int i = 0; i < sizeMass; i++) {
this->push(objs[i]);
}
}
//----------------DESTRUCTOR-------------------
~Stack() {
delete[] stackPr;
}
//-----------------METHODS---------------------
//Add element to stack
void push(T &element) {
if (top == size - 1)
cout << "\nThere's no more place!!!\n";
else {
top++;
stackPr[top] = element;
cout << "\nElement was succesfully pushed\n";
}
}
//Read + Delete
T pop() {
if (top == -1)
cout << "\nStack is empty\n";
else {
T temp = stackPr[top];
stackPr[top] = 0;
top--;
cout << "\nElement was succesfully poped and deleted\n";
return temp;
}
}
//Read
T popup() {
if (top == -1)
cout << "\nStack is empty\n";
else {
cout << "\nElement was succesfully popped\n";
return stackPr[top];
}
}
//Comparison of 2 stacks
bool comparison(T &stack) {
if (size == stack.size)
for (int i = 0; i < size; i++) {
if (!this->stackPr[i].comparison(stack.stackPr[i]))
return false;
}
else
return false;
return true;
}
};
Try this, in your Stack class
change:
bool comparison(T &stack) {
for this:
bool comparison(Stack<T> &stack) {
First of all, abandon this comparison function, it hinders your code, use == instead.
Secondly, use const Stack<T> in your comparison function.
And finally, use auto to deduce the type of the variables.
Here is an example that shows the basics of what I just wrote:
#include <iostream>
using namespace std;
struct Time
{
bool operator==(const Time& time)
{
return true;// adjust it with your own needs.
}
};
template<typename T>
struct Stack
{
T val;
Stack(T& val_): val(val_) {}
bool operator==(const Stack<T>& stack)
{
return this->val == stack.val; // here is your business logic of comparison
}
};
int main()
{
Time t1;
Time t2;
Stack<Time> myStack1(t1);
Stack<Time> myStack2(t2);
auto temp = myStack1 == myStack2;
cout << temp << endl;
return 0;
}