Insert method overloading - c++

I am trying to overload Insert() method in C++. Here is my code which i had come up with
Below is my List.h file
#ifndef _LIST_H_
#define _LIST_H__
#include "stdafx.h"
#include <cstdlib>
#include <iostream>
class List
{
public:
List(size_t capacity = 5); // constructor - allocates dynamic array
~List(); // destructor
void insert(size_t position, int value);
void printArray();//Printing Array elements
private:
void resize(size_t new_size); // allocate new larger array
int *data_; // dynamic array
size_t size_; // size of dynamic array
size_t capacity_; // capacity of dynamic array
};
inline int& List::operator [] (size_t pos)
{
if (pos >= 0 && pos <= size_ - 1)
{
return data_[pos];
}
}
#endif _LIST_H_
This is my List.cpp file
#include "stdafx.h"
#include "List.h"
#include <iostream>
using namespace std;
List::List(size_t capacity)
{
data_ = new int[capacity];
capacity_ = capacity;
size_ = 0;
}
List::~List()
{
cout << "delete ";
delete[] data_;
}
void List::insert(size_t position, int value) {
if (size_ == capacity_)
{
resize(2 * capacity_);
}
if (position >= 0 && position <= capacity_ - 1)
{
data_[position] = value;
size_++;
}
}
void List::printArray()
{
size_t i;
for (i = 0; i < size_; i++)
{
cout << data_[i]<<" ";
}
}
void List::resize(size_t new_size)
{
int * temp;
size_t i;
capacity_ = new_size;
temp = new int[capacity_];
for (i = 0; i <= size_; ++i)
{
temp[i] = data_[i];
}
delete[] data_;
data_ = temp;
}
main method file
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
//List d,a;
List *arr,*temp;
arr = new List(10);
temp = new List();
arr->insert(1, 3);
cout << "Printing array list after inserting: " << endl;
arr->printArray();
}
Output:
Testing Insert method:
Printing array list after inserting:
-842150451
Expected:
Testing Insert method:
Printing array list after inserting:
3
suppose if i have array like arr =[1,2,3,4]; arr->insert(2,-2). Output should be arr= [1,2,-2,3,4]
Can any one tell me why it is displaying a random number instead of inserted value and How to modify the code

You should change this line:
arr->insert(1, 3);
into:
arr->insert(0, 3);

Related

Dynamic Array resizing in C++ Doesn't work properly

i have this reSize function in my Array header
void reSize(int newsize) {
T* old = items;
size = newsize;
items = new T[newsize];
for (int i = 0;i < length;i++)
items[i] = old[i];
delete[]old;
}
and my main code:
struct User{
string name;
Array<int> data;
};
int main() {
Array<User> x(3);
x.get(0).name = "Kmal";
x.get(0).data.push_back(2); x.get(0).data.push_back(3);
x.reSize(10);
cout << x.get(0).data.get(0) <<endl;
return 0;
}
the problem is after resizing, my values that were stored in "data" variable are gone.
when i commented the code.
//delete[] old
in the reSize function
it worked fine...so i guess the problem is when i delete the pointer it deletes also the pointer inside the struct object which i don't want it to happen..
i don't want to comment the command becuz a leak in the memory will happen...how to fix this problem ?.
Update: My Array Class .
#include <iostream>
using namespace std;
template <class T>
class Array {
private :
T* items;
int size;
int length;
public :
Array() {
this->size = 0;
items = new T[this->size];
length = 0;
}
Array(int size) {
this->size = size;
items = new T[this->size];
length = 0;
}
int getsize() {
return this->size;
}
template <class T> void push_back(T x) {
if ((length+1) <= size) {
items[length] = x;
length++;
}
else {
this->reSize(size+1);
items[length] = x;
length++;
}
}
template <class T> void Insert(int index, T x) {
if (length + 1 <= size) {
for (int i = length;i > index;i--) {
items[i] = items[i - 1];
}
items[index] = x;
length++;
}
else {
this->reSize(size+1);
for (int i = length;i > index;i--) {
items[i] = items[i - 1];
}
items[length] = x;
length++;
}
}
template <class T> int Find(T x) {
int index = -1;
for (int i = 0;i < length;i++) {
if (items[i] ==x) {
index = i;
break;
}
}
return index;
}
void remove(int index) {
items[index] = "";
if(index+1 < length)
for (int i = index;i < length-1;i++) {
items[i] = items[i + 1];
items[i + 1] = "";
}
length--;
}
void reSize(int newsize) {
T* old = items;
size = newsize;
items = new T[newsize];
for (int i = 0;i < length;i++)
items[i] = old[i];
delete[]old;
}
void Merge(Array<T> x){
T* old = items; int oldlength = length;
items = new T[size + x.size];
size = size + x.size;
length += x.length;
for (int i = 0;i < length;i++) {
if(i< oldlength)
items[i] = old[i];
else
items[i] = x.items[i-oldlength];
}
delete[] old;
}
T& get(int index) {
return items[index];
}
}
struct User{
string name;
Array<int> data;
};
int main() {
Array<User> x(3);
// this line causes some problems
x.get(0).name = "Kmal";
x.get(0).data.push_back(2); x.get(0).data.push_back(3);
x.reSize(10);
cout << x.get(0).data.get(0) <<endl;
return 0;
}
In your code, declaring Array<User> x(3) declares an empty array with 3 elements that are preallocated. The length property of the array is 0. When the array is copied, length(0) elements are copied over into the resized storage. When you access the 0th element, it won't be copied on resize. What you actually need to do is call push_back() to add an element to the array so that length becomes 1 and the element is copied on resize.
Also, your array class is lacking a proper copy constructor and move constructor, which means copying it won't work at all. This means that User cannot be copied properly since it contains an array, which means that resizing an array of User won't work. You need to implement a copy constructor and copy assignment operator to be able to copy the array. You also need a destructor since, right now, the array is leaking memory when it goes out of scope.

How to insert element using template

I have some doubts about my insert method. it is compiling, but with no result. I presume that it is containing some coding errors. Can you help me resolving this? Thanks in advance.
private:
T* elements;
int capacity;
int nbElements;
template <class T>
void TableDynamic<T>::insert(const T& element, int index)
{
int *temp = new int[capacity] ;
for(int i =0; i<nbElements; i++)
{
temp[i] = element;
}
delete[] elements;
int *elem = new int[capacite];
}
I have written some code for you. see if its works for you.
#include <iostream>
using namespace std;
// insert element using template
template <class T>
class TableDynamic
{
private:
T *elements;
int capacity;
int nbElements;
public:
TableDynamic(int capacity)
{
this->capacity = capacity;
this->nbElements = 0;
this->elements = new T[capacity];
}
void insert(const T &element, int index)
{
if (index < 0 || index > nbElements)
{
cout << "Index out of range" << endl;
return;
}
if (nbElements == capacity)
{
cout << "Table is full" << endl;
return;
}
for (int i = nbElements; i > index; i--)
{
elements[i] = elements[i - 1];
}
elements[index] = element;
nbElements++;
}
void print()
{
for (int i = 0; i < nbElements; i++)
{
cout << elements[i] << " ";
}
cout << endl;
}
};
int main()
{
TableDynamic<int> table(10);
table.insert(10, 0);
table.insert(20, 1);
table.insert(30, 2);
// print the table
table.print();
return 0;
}
temp and elem variables types should be T* , and in the last line you have wrote capacite, should be capacity
Resizing should only be done, if the capacity is insufficient.
Furthermore you didn't copy any of the old elements over; you simply fill every element with the new element.
Also you're generating an array of ints regardless of element type which will only allow for element types int or const int.
The code should look something like this:
template <class T>
void TableDynamic<T>::insert(const T& element, int index)
{
if ((index > nbElements) || (index < 0))
{
throw std::runtime_error("invalid index");
}
if ((nbElements + 1) > capacity)
{
// reallocate array
auto newCapacity = CalculateNewCapacity(capacity, nbElements + 1); // todo: implement capacity calulation function
auto temp = std::make_unique<T[]>(newCapacity);
temp[index] = element; // note copying may result in an error, moving shouldn't, so copy first
// move first half
std::move(elements, elements + index, temp.get());
// move second half
std::move(elements + index, elements + nbElements, temp.get() + (index + 1));
// replace array
delete[] elements;
elements = temp.release();
capacity = newCapacity;
}
else
{
// make room for new element
std::move_backward(elements + index, elements + nbElements, elements + (nbElements + 1));
// insert new element
elements[index] = element;
}
++nbElements;
}

How to pass the array directely to a C++ constructor

So I wrote this C++ Class for storing an Array:
#include<bits/stdc++.h>
using namespace std;
class Array
{
private:
int size;
int *A = new int[size];
int length;
public:
Array(int arr[],int sz = 10)
{
length = sz;
size = 10;
for(int i=0;i<length;i++)
A[i] = arr[i];
}
~Array()
{
delete []A;
}
void Display();
void Insert(int index, int x);
};
void Array::Display()
{//code}
void Array::Insert(int index, int x)
{//code}
int main()
{
int a[3] = {1,2,3};
Array arr(a, 3);
arr.Display();
arr.Insert(1,4);
arr.Display();
}
This works fine. But in the main() function:
int main()
{
int a[3] = {1,2,3};
Array arr(a, 3);
arr.Display();
}
I am passing the pointer to the array a in the Class constructor.
Is there a way to pass the array like this?
Array arr({1,2,3}, 3);
You probably need to use something like this. But please note this code is still not optimal and it is usually much better to use std::vector or in some cases std::array.
#include <initializer_list>
class Array
{
private:
int *m_data = nullptr;
int m_size = 0;
int m_capacity = 0;
public:
Array(int arr[], int sz = 10) {
m_size = sz;
m_capacity = sz;
m_data = new int[m_capacity];
for(int i=0; i < m_size; i++) {
m_data[i] = arr[i];
}
}
Array(const std::initializer_list<int> &il) {
m_size = il.size();
m_capacity = il.size();
m_data = new int[m_capacity];
auto it = il.begin();
for (int i = 0; i < m_size; ++i) {
m_data[i] = *it;
++it;
}
}
~Array() {
delete [] m_data;
}
int size() const { return m_size; }
bool empty() const { return m_size == 0; }
int& operator[](int id) { return m_data[id]; }
int operator[](int id) const { return m_data[id]; }
};
#include <cstdio> // for printf
int main() {
Array arr({1,2,3});
printf(" %i \n",arr.size());
return 0;
}

Object on heap gets deleted right after creation

I'm writing a Vector class for my uni the task is to create a method that mutates the elements of this "vector" class into an object of the class itself and returns this object.
My problem is that as soon as I create the Object I should return it gets deleted from the heap.
I create a new Object from the class itself with new DynArray{} and push back the nonmutated elements into the Object. The problem is that before I even can use the Object (push the elements into the "Vector") it got deleted and is not present anymore. Therefore the program crashes. How can I avoid that from happening?
The mutation should take place in the method transform.
header file:
#ifndef DYNARRAY_H
#define DYNARRAY_H
#include <array>
#include <exception>
#include <iostream>
#include <functional>
class DynArray
{
public:
DynArray();
DynArray(int c);
DynArray(DynArray& copyArr);
~DynArray();
int& at(const int i);
int size();
int capacity();
void print();
void push_back(const int value);
void pop_back();
void erase(const int index);
void apply(std::function<void(int&)> f);
DynArray transform(std::function<int(int)> f);
void sort();
void sort(std::function<bool(int,int)> comp);
private:
int _capacity;
int _size;
int * arr = nullptr;
};
#endif // DYNARRAY_H
class file:
#include <dynarray.h>
DynArray::DynArray(){
DynArray(4);
}
DynArray::DynArray(int c) : _capacity{c+=c}, _size{0} {
arr = new int[_capacity];
}
DynArray::DynArray(DynArray& copyArr) : _capacity{copyArr.capacity()}, _size{copyArr.size()}{
arr = new int[_capacity];
for(int i = 0; i < copyArr.size(); i++)
arr[i] = copyArr.at(i);
}
DynArray::~DynArray(){
delete [] arr;
}
...
int& DynArray::at(const int i){
if( i >= 0 && i <= size() && size() > 0)
return arr[i];
else
throw std::invalid_argument("illegal Index");
}
int DynArray::size(){
return _size;
}
int DynArray::capacity(){
return _capacity;
}
...
void DynArray::push_back(const int value){
if(size() >=capacity()){
int * tmp = arr;
_capacity+=_capacity;
arr = new int[_capacity];
for(int i = 0; i < size(); i++){
arr[i] = tmp[i];
}
delete [] tmp;
tmp = nullptr;
arr[size()] = value;
_size++;
}else{
arr[size()] = value;
_size++;
}
}
void DynArray::pop_back(){
if(size() == 0)
throw std::runtime_error("Cant delete a non existing element");
else{
at(size()-1) = 0;
_size--;
}
}
void DynArray::erase(const int index){
if( index >= 0 && index < size() && size() > 0){
for(int i = index; i < (size()-1); i++){
arr[i] = arr[i+1];
}
_size--;
}else{
throw std::invalid_argument("illegal Index");}
}
...
DynArray DynArray::transform(std::function<int(int)> f){
DynArray * copyArr = new DynArray();
for(int i = 0; i < size()-1; i++)
copyArr->push_back(at(i));
for(int i = 0; i < copyArr->size()-1; i++)
f(copyArr->at(i));
return *copyArr;
}
main:
int main()
{
DynArray a(1);
a.push_back(1);
a.push_back(3);
a.push_back(44);
a.push_back(677);
a.push_back(23423);
a.push_back(312);
a.push_back(5645);
a.push_back(5645);
a.push_back(5213145);
a.push_back(561234785);
a.push_back(5675467);
a.print();
std::cout << std::endl;
a.pop_back();
a.pop_back();
a.print();
std::cout << std::endl;
a.erase(5);
a.erase(0);
a.print();
std::cout << std::endl;
DynArray bb;
bb = a.transform(addOne);
bb.print();
std::cout << std::endl;
}
Changed the default and copy constructor as suggested:
DynArray::DynArray() : _capacity{4}, _size{0}{}
...
DynArray::DynArray(const DynArray& copyArr) : _capacity{copyArr._capacity}, _size{copyArr._size}{
arr = new int[_capacity];
//createNewArray(_capacity);
for(int i = 0; i < _size; i++)
arr[i] = copyArr.arr[i];
}

Stack of strings. Deleting an even element

everyone!
I'm trying to do such task:
Create stack od strings, by writing several constructors, including copy constructor. All elements are hleds in an array. If an array have fixed size, in case of overloading, increase it. Create pop(), push() functions. Make a function, deleting every even element.
Got problem, after sizing of the stack
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <cstddef>
using namespace std;
class Stack
{
string *stck; //stack pointer
int sz; //stack size
int ts; //top of the stack
public:
//constructor
Stack(int size)
{
size=sz;
stck = new string[sz];
ts = -1;
};
//destructor
~Stack() {
delete []stck;
};
//copy constructor
Stack (const Stack &ob);
void Push(string itm);
string Pop();
void Show(int sz);
private:
void Resize(int sz);
};
void Stack::Push(string itm)
{
if (ts == sz)
{
cout<<"Stack is overflow"<<endl;
Resize(ts);
}
else stck[ts++] = itm;
}
string Stack::Pop()
{
if(ts<0)
{
cout<<"Stack is free"<<endl;
return 0;
}
else return stck[--ts];
}
void Stack::Show(int sz)
{
for (int i = 0; i < sz; i++)
{
std::cout << stck[i] << std::endl;
}
}
Stack::Stack (const Stack &ob)
{
cout<<"Copy constructor allocating stackPtr)"<<endl;
stck = new string;
*stck = *ob.stck;
}
//функция выделения дополнительной памяти
void Stack::Resize(int idx)
{
int new_size = sz;
while (new_size < idx)
new_size *=2;
string *new_arr = new string[new_size];
for(int i = 0; i < sz; i++)
new_arr[i] = stck[i];
delete[] stck;
stck = new_arr;
sz = new_size;
}
int main()
{
cout<<"Enter the size of the stack"<<endl;
int n;
cin>>n;
Stack mystck(n);
string str;
for(int i=0; i<n; i++)
{
cout<<"Enter an element"<<endl;
cin>>str;
mystck.Push(str);
}
for(int j = 0; j<n; j+2)
{
mystck.Pop();
mystck.Show(n);
}
return 0;
}
Can anybody help me with fixing that case?