Copying data in a simple vector class - c++

I'm trying write my own vector class:
template <typename T>
class Vector {
public:
Vector(int default_size = 2) :
size(0), data_member(new T[default_size]), capacity(default_size) {};
Vector(const Vector& obj)
{
data_member = new T[obj.size];
data_member = obj.data_member;
size = obj.size;
capacity = obj.capacity;
}
void push_back(T& elem)
{
if (size == capacity)
resize(2 * size);
data_member[size] = elem;
size++;
}
void push_front(T& data)
{
if (size + 1 == capacity)
resize(2 * size);
for (int i = size - 1; i >= 0; i--)
{
data_member[i + 1] = data_member[i];
}
data_member[0] = data;
size++;
}
void pop_back()
{
--size;
}
void resize(int size_)
{
if (size_ > capacity)
{
T* temp = new T[size_];
memcpy(temp, data_member, size * sizeof(T));
delete[] data_member;
data_member = new T[size_];
data_member = temp;
//delete[] temp;
capacity = size_;
}
}
int get_size() { return size; }
T* getarr() { return data_member; }
private:
T* data_member;
int size;
int capacity;
};
and here is a main for testing my class
int main()
{
Vector<int> myint;
int a = 5, b = 8, c = 9;
myint.push_back(a);
myint.push_back(b);
myint.push_back(c);
Vector<int> you = myint;
int* arr1 = you.getarr();
for (int i = 0; i < you.get_size(); i++)
{
cout << *arr1 << endl;
arr1++;
}
cout << endl << endl;
int h[3] = { 1,2,3 };
int* hp = h;
int g[3] = { 4,5,6 };
int* gp = g;
int f[3] = { 4,5,6 };
int* fp = f;
Vector<int*> myarrint;
myarrint.push_back(hp);
myarrint.push_back(gp);
myarrint.push_back(fp);
int** arr = myarrint.getarr();
for (int i = 0; i < myarrint.get_size(); i++)
{
for (int j = 0; j < 3; j++)
{
cout << **arr << endl;
(*arr)++;
}
arr++;
}
cout << endl << endl;
Vector<string> mystr;
string s1 = "I";
string s2 = "went";
string s3 = "shopping";
mystr.push_back(s1);
mystr.push_back(s2);
mystr.push_back(s3);
string* str1 = mystr.getarr();
for (int i = 0; i < mystr.get_size(); i++)
{
cout << *str1 << endl;
str1++;
}
cout << endl << endl;
string i = "wow";
mystr.push_front(i);
string* str2 = mystr.getarr();
for (int i = 0; i < mystr.get_size(); i++)
{
cout << *str2 << endl;
str2++;
}
cout << endl << endl;
return 0;
}
I'm new in c++ and I'm really confused, I think in my push_back function, I'm just making my objects point to temp and I'm not copying temp in them , so if I want to delete temp in the end of my push_back function my data_members will be lost. So what is the right way to do so?
second if I want to make a dynamic array of strings my program will crash sometimes, and I think ,it's because of memcpy() in my resize function, still I don't know what should I do instead of it?

Related

'this' cannot be used in a constant expression error

The error is on line 76 int res[mSize]; the problem is on mSize. It seems like a simple fix but I can't figure it out. If someone can figure it out or point me in the right direction that would be greatly appreciated.
Also, the deconstructor ~MyContainer(), I am not sure if I am using it right or if there is a correct place to put it.
Here is my code:
#include <iostream>
using namespace std;
class MyContainer
{
private:
int* mHead; // head of the member array
int mSize; // size of the member array
public:
MyContainer();
MyContainer(int*, int);
//~MyContainer();
void Add(int);
void Delete(int);
int GetSize();
void DisplayAll();
int FindMissing();
~MyContainer() {}
};
MyContainer::MyContainer()
{
mHead = NULL;
mSize = 0;
}
MyContainer::MyContainer(int* a, int b)
{
mHead = a;
mSize = b;
}
void MyContainer::Add(int a)
{
*(mHead + mSize) = a;
mSize++;
}
void MyContainer::Delete(int a)
{
int index;
for (int i = 0; i < mSize; i++)
{
if (*(mHead + i) == a)
{
index = i;
break;
}
}
for (int i = index; i < mSize; i++)
{
*(mHead + i) = *(mHead + i + 1);
}
mSize--;
}
int MyContainer::GetSize()
{
return mSize;
}
void MyContainer::DisplayAll()
{
cout << "\n";
for (int i = 0; i < mSize; i++)
{
cout << *(mHead + i) << " ";
}
}
int MyContainer::FindMissing()
{
int res[mSize];
int temp;
int flag = 0;
for (int i = 1; i <= mSize; i++)
{
flag = 0;
for (int j = 0; j < mSize; j++)
{
if (*(mHead + j) == i)
{
flag = 1;
break;
}
}
if (flag == 0)
{
temp = i;
break;
}
}
return temp;
}
int main()
{
const int cSize = 5;
int lArray[cSize] = { 2, 3, 7, 6, 8 };
MyContainer lContainer(lArray, cSize);
lContainer.DisplayAll();
lContainer.Delete(7);
lContainer.DisplayAll();
cout << "Size now is: " << lContainer.GetSize() << endl; lContainer.Add(-1);
lContainer.Add(-10);
lContainer.Add(15);
lContainer.DisplayAll();
cout << "Size now is: " << lContainer.GetSize() << endl;
cout << "First missing positive is: " << lContainer.FindMissing() << endl;
system("PAUSE"); return 0;
}
int res[mSize];
The size of the array mSize must be known at compile time. You cannot use a variable here. An option may be to define a macro with an largish value that will not exceeded.
static const int kLargeSize =100;
int res[kLargeSize];
Edited in response to the comments - const and constexpr are a better option than a macro.
Or even better, you can use std::vector - https://en.cppreference.com/w/cpp/container/vector

Can't manage to display the last array

I have these code:
#include<iostream>
#include<iomanip>
using namespace std;
class Array {
private:
static const int size = 100;
int arr[size];
public:
Array();
void display();
Array& operator+(const Array& arr);
};
Array::Array()
{
for (int i = 0; i < size; i++)
{
arr[i] = rand() % 99 + 1;
}
}
void Array::display()
{
for (int i = 0; i < size; i++)
{
cout << setw(5) << arr[i];
if ((i + 1) % 10 == 0)
cout << endl;
}
}
Array & Array::operator+(const Array & arr)
{
Array temp;
for (int i = 0; i < size; i++)
{
temp.arr[i] = this->arr[i] + arr.arr[i];
}
return temp;
}
int main()
{
srand(time(NULL));
Array arr1, arr2;
cout << "arreglo 1:\n";
arr1.display();
cout << endl;
cout << "arreglo 2:\n";
arr2.display();
cout << endl;
//adding both arr HERE IS MY PROBLEM
Array arr3 = arr1 + arr2;
cout << "Suma de arreglo 1 y arreglo 2: " << endl;
arr3.display();
cout << endl;
return 0;
}
Somehow it can't manage to display Array arr3 = arr1 + arr2.
Array & Array::operator+(const Array & arr)
{
Array temp;
...
return temp;
}
This returns a reference to an object that goes out of scope and is destroyed after the function returns. As a general rule you should not return addresses of or references to local variables.
Remove the & so it returns a new Array instead:
Array Array::operator+(const Array & arr)

How do I write a moving Average to an array list class?

I'm trying to make an arraylist class where I make a moving Average function in my arraylist class while outputting the moving average of my arraylist class.
I've tried various research and examples online and I've officially hit a wall. Can someone please help me fix my problem. I really need to get this fixed as soon as possible. Code was provided by my professor.
#ifndef ARRAYLIST_H_
#define ARRAYLIST_H_
#include<iostream>
using namespace std;
class arrayList {
int size;
int capacity;
double * p;
void resize() {
capacity *= 2;
double * temp = new double[capacity];
for (int i = 0; i < size; i++) {
temp[i] = p[i];
}
delete[] p;
p = temp;
}
}
public:
arrayList(): size(0), capacity(1) {
p = new double[capacity];
}
arrayList(int cap): size(0), capacity(cap) {
p = new double[capacity];
}
//copy constructor
arrayList(const arrayList & copy) {
size = copy.size;
capacity = copy.capacity;
p = new double[capacity];
for (int i = 0; i < size; ++i)
p[i] = copy.p[i];
}
//move constructor
arrayList(arrayList && move) {
size = move.size;
capacity = move.capacity;
p = move.p;
move.size = 0;
move.capacity = 0;
move.p = nullptr;
}
//copy assignment operator
arrayList & operator = (const arrayList & copyA) {
if (this != & copyA) {
size = copyA.size;
capacity = copyA.capacity;
p = new double[capacity];
for (int i = 0; i < copyA.size; ++i)
p[i] = copyA.p[i];
delete[] p;
}
return *this;
}
// move assignment operator
arrayList & operator = (arrayList moveA) {
if (this != & moveA) {
size = moveA.size;
capacity = moveA.capacity;
delete[] p;
p = moveA.p;
moveA.p = nullptr;
}
return *this;
}
//destructor
~arrayList() {
delete[] p;
}
void insert(int index, int value) {
if (index >= capacity) {
cout << "OUT OF BOUNDS!";
}
if (index < size && index >= 0) {
for (int i = size; i > index; --i) {
p[i] = p[i - 1];
}
p[index] = value;
size++;
} else {
p[index] = value;
size++;
}
}
void append(int val) {
if (size == capacity)
resize();
p[size] = val;
size++;
}
void movingAvg(const arrayList & val, int kernel) {
for (int i = 0; i < val.size; ++i) {
kernel = val.p[i];
val.p[i] = kernel[val.size - 1 - i];
kernel[size - 1 - i] = kernel;
cout << "average of the array is: " << val.p;
}
friend ostream & operator << (ostream & os, arrayList & val) {
for (int i = 0; i < val.size; ++i)
os << val.p[i] << " ";
os << endl << endl;
return os;
}
};
// main.cpp
int main() {
arrayList a;
a.append(45);
cout << a;
a.append(14);
cout << a;
a.insert(2, 76);
cout << a;
//CRASHES AT THIS POINT!
a.insert(3, 45);
cout << a;
a.insert(5, 23);
cout << a;
return 0;
}
OUTPUT:
45
45 14
45 14 76 0
You are deleting p more than once in your resize function. That's likely the source of your crash.
Instead of this:
void resize(){
capacity *= 2; //THIS IS WHAT'S CRASHING THE CODE
double *temp = new double[capacity];
for(int i = 0; i < size; i++){
temp[i] = p[i];
delete []p;
p = temp;
temp = nullptr;
}
}
Implement this:
void resize() {
capacity *= 2;
double *temp = new double[capacity];
for (int i = 0; i < size; i++) {
temp[i] = p[i];
}
delete [] p;
p = temp;
}
And if you want to be more efficient with the copy loop:
void resize() {
capacity *= 2;
double *temp = new double[capacity];
memcpy(temp, p, sizeof(double)*size);
delete [] p;
p = temp;
}

Code runs when in main() but gives error when in function [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I am writing a dynamic matrix class that stores each non-zero value as a List of 3 elements [row,column,value]
I made a dynamic array class called "List", and class"Matrix" a List of list pointers.
My code to transpose the Matrix works:
void transpose(Matrix tripleList)
{
for (int i = 0; i < tripleList.getNumOfElem(); i++)
{
List* list = new List;
(*list).copy(*(tripleListMatrix.getAt(i)));
int temp = (*list).getAt(0);
(*list).set(0, (*list).getAt(1));
(*list).set(1, temp);
(*list).displayList();
cout << "\n";
}
}
it works when written directly in main() but gives error when in stand alone function. can anyone explains why and how to fix it?
Full code:
#include <iostream>
using namespace std;
class List //a dynamic int pointer array
{
private:
int capacity;
int numOfElem;
int *arr;
//initialize all values in capacity to 0
void initialize(int from)
{
for (int i = from; i < capacity; i++)
{
arr[i] = 0;
}
}
//double the capaicty, then initialize
void expand()
{
capacity *= 2;
int *tempArr = new int[capacity];
for (int i = 0; i < numOfElem; i++)
tempArr[i] = arr[i];
delete[] arr;
arr = tempArr;
initialize(numOfElem);
}
public:
List()//constructor
{
capacity = 10;
numOfElem = 0;
arr = new int[capacity];
}
~List()//destrcutor
{
delete[] arr;
}
//add int to the end of List
void append(int newElement)
{
if (numOfElem >= capacity)
expand();
arr[numOfElem++] = newElement;
}
//Copy all element of an input list to the end of List
void copy(List list)
{
for (int i = 0; i < list.getNumOfElem(); i++)
{
if (numOfElem >= capacity)
expand();
arr[numOfElem++] = list.getAt(i);
}
}
//get reference of the int at an index in te list
int* getAddress(int index)
{
if (index < 0 || index >= numOfElem)
throw ("Out of bounds exception!!!");
return &arr[index];
}
//change the value of at specific index
void set(int index, int value)
{
arr[index] = value;
}
//get int at an index in te list
int getAt(int index)
{
if (index < 0 || index >= numOfElem)
throw ("Out of bounds exception!!!");
return arr[index];
}
int getNumOfElem()
{
return numOfElem;
}
void displayList()
{
for (int i = 0; i < numOfElem; i++)
{
cout << arr[i] << " ";
}
}
};
class Matrix //a List of list pointers
{
private:
int capacity;
int numOfElem;
List* *arr;
void initialize(int from)
{
for (int i = from; i < capacity; i++)
{
arr[i] = new List;
}
}
void expand()
{
capacity *= 2;
List* *tempArr = new List*[capacity];
for (int i = 0; i < numOfElem; i++)
tempArr[i] = arr[i];
delete[] arr;
arr = tempArr;
initialize(numOfElem);
}
public:
Matrix()
{
capacity = 10;
numOfElem = 0;
arr = new List*[capacity];
}
~Matrix()
{
delete[] arr;
}
void append(List* newElement)
{
if (numOfElem >= capacity)
expand();
arr[numOfElem++] = newElement;
}
void set(int index, List* value)
{
arr[index] = value;
}
List* getAt(int index)
{
if (index < 0 || index >= numOfElem)
throw ("Out of bounds exception!!!");
return arr[index];
}
int getNumOfElem()
{
return numOfElem;
}
};
void transpose(Matrix tripleList)
{
for (int i = 0; i < tripleList.getNumOfElem(); i++)
{
{
List* list = new List;
(*list).copy(*(tripleListMatrix.getAt(i)));
int temp = (*list).getAt(0);
(*list).set(0, (*list).getAt(1));
(*list).set(1, temp);
(*list).displayList();
cout << "\n";
}
}
int main()
{
int m, n, input;
cout << "Please enter the number of rows and columns of the matrix :\n";
cin >> m >> n;
Matrix tripleListMatrix;
int k = 0;
cout << "Please enter the matrix : \n";
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
cin >> input;
if (input != 0)
{
tripleListMatrix.append(new List);
(*(tripleListMatrix.getAt(k))).append(i + 1);
(*(tripleListMatrix.getAt(k))).append(j + 1);
(*(tripleListMatrix.getAt(k))).append(input);
k++;
}
}
}
cout << "The triple list of matrix is:\n";
for (int i = 0; i < tripleListMatrix.getNumOfElem(); i++)
{
(*(tripleListMatrix.getAt(i))).displayList();
cout << "\n";
}
cout << "\n\n";
//transpose(tripleListMatrix);
//the code below is the same as in the function transpose but transpose gives error
for (int i = 0; i < tripleListMatrix.getNumOfElem(); i++)
{
List* list = new List;
(*list).copy(*(tripleListMatrix.getAt(i)));
int temp = (*list).getAt(0);
(*list).set(0, (*list).getAt(1));
(*list).set(1, temp);
(*list).displayList();
//cout << "\t" << list;
cout << "\n";
}
cout << "\n\n";
//checking that tripleListMatrix is unchanged
for (int i = 0; i < tripleListMatrix.getNumOfElem(); i++)
{
(*(tripleListMatrix.getAt(i))).displayList();
cout << "\n";
}
return 0;
}
List* *arr;
When you call transpose(), it makes a copy Matrix because you're not passing by reference. That copy just has a copy of the address for your List, not it's own List object. When the destructor runs on the copy, it clears up the allocated memory, but the original Matrix object in main still points to that same memory. When that object goes away, its destructor tries to free the same memory again and that's bad.
You probably meant:
void transpose(Matrix const & tripleList)
So that no copy is made when calling transpose(), but you should also explicitly delete the copy construtor of Matrix so it cannot be called
Matrix(Matrix const &) = delete;
or make an explicit Matrix copy constructor that makes a deep copy of the memory.

How to access elements of the array just by having the array's memory location? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
So, this is just few methods from my myArray.cpp class. It gives me error on
setSize(orig.getsize());
for(int i = 0; i<getSize();i++)
setData(i,orig.getData(i));
these above code(error - which is non-class type double). can anyone please help me? I'm trying to copy an array to the object array
myArray::myArray(double* orig, int size) {
setSize(orig.getsize());
for(int i = 0; i<getSize();i++)
setData(i,orig.getData(i));
}
void myArray::setSize(int value) {
if (value > 0) {
size = value;
}
}
void myArray::setData(int index, double value) {
if ((index >= 0) && (index < size)) {
arr[index] = value;
} else {
// cout << "NO!" << endl;
}
}
double myArray::getData(int index) const {
if ((index >= 0) && (index < size)) {
return arr[index];
} else {
return arr[size - 1];
}
}
That's my main.cpp class
#include <iostream>
#include "myArray.h"
//#include "myArray.cpp"
using namespace std;
int main (int argc, char **argv)
{
cout << "**************Testing Default Constructor*****************" << endl;
myArray A1;
cout << "A1: ";
A1.print();
cout << "**************Testing Alt Constructor 1*****************" << endl;
myArray A2(5,0);
cout << "A2: ";
A2.print();
cout << "**************Testing init*****************" << endl;
A2.init();
cout << "A2 after init: ";
A2.print();
int size = 5;
double *temp = new double[size];
for(int i = 0; i < size; i++)
{
temp[i] = i;
}
cout << "**************Testing Alt Constructor 2*****************" << endl;
myArray A3(temp, size);
cout << "A3: ";
cout << A3.getSize();
cout << endl;
cout << "Fe";
A3.print();
That's my myArray.cpp class
#ifndef MYARRAY_H_INCLUDED
#define MYARRAY_H_INCLUDED
/***************************************************************************
* myArray class header file
***************************************************************************/
class myArray
{
public:
myArray();
myArray(int,double);
myArray(double*, int);
~myArray();
int getSize() const;
bool equal(const myArray &rhs) const;
void setData(int index, double value);
void insert(int, double);
void remove(int);
double get(int);
void clear();
int find(double);
bool equals(myArray&);
void print() const;
void init();
double getData(int index) const;
// void init();
// void print() const;
void expand();
private:
int size;
double *arr;
void setSize(int value);
};
#endif // MYARRAY_H_INCLUDED
That's my myArray.cpp class where I'm getting the error in the default paramaterized constructor
#include "myArray.h"
#include <iostream>
using namespace std;
myArray::myArray() : size(0) {
// size = 10;
arr = new double [size];
}
/*myArray::myArray(int _size) : size(_size) {
// size = _size;
arr = new double [size];
for (int i = 0; i < size; i++) {
arr[i] = i;
}
} */
myArray::myArray(int _size, double value) : size(_size) {
// size = _size;
arr = new double [size];
for (int i = 0; i < size; i++) {
arr[i] = value;
}
}
/*myArray::myArray(myArray* temp, int size)
{
setSize(temp.getSize());
for (int i = 0; i < getSize(); i++) {
setData(i, temp.getData(i));
}
} */
myArray::myArray(double* orig, int size) {
setSize(orig.getsize());
for(int i = 0; i<getSize();i++)
setData(i,orig.getData(i));
//double arr[size];
// arr = new double[size];
// p = orig;
// for(int i = 0;i<size;i++)
// {
// arr[i] = orig[i];
// cout << arr[i] << " ";
// }
// cout << endl;
// setSize(size);
// for (int i = 0; i < getSize(); i++)
// setData(i, orig.getData(i));
// cout << "hell";
// for (int i = 0; i < size; i++) {
// arr[i] = myArray[i];
// cout << arr[i];
//}
// arr = myArray;
}
myArray::~myArray() {
delete [] arr;
}
int myArray::getSize() const {
return size;
}
void myArray::setSize(int value) {
if (value > 0) {
size = value;
}
}
void myArray::setData(int index, double value) {
if ((index >= 0) && (index < size)) {
arr[index] = value;
} else {
// cout << "NO!" << endl;
}
}
double myArray::getData(int index) const {
if ((index >= 0) && (index < size)) {
return arr[index];
} else {
return arr[size - 1];
}
}
void myArray::print() const {
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
void myArray::expand() {
double *localArray = new double[size + 1];
for (int i = 0; i < size; i++) {
localArray[i] = arr[i];
}
localArray[size] = size;
delete [] arr;
setSize(size + 1);
arr = localArray;
// myArray = new int[size];
//
// //Is this a deep-copy or a shallow-copy?
// //Can you replace one with the other?
// //What are the advantages and disadvantages?
// for(int i=0; i < size; i++) {
// myArray[i] = localArray[i];
// }
// delete [] localArray;
}
bool myArray::equal(const myArray& rhs) const {
bool result(true);
if (getSize() != rhs.getSize()) {
result = false;
} else {
for (int i = 0; i < getSize(); i++) {
if (getData(i) != rhs.getData(i)) {
result = false;
}
}
}
return result;
}
void myArray::init()
{
cout << "Enter the " << size << " elements to populate the array " << endl;
for(int i = 0;i<getSize();i++)
{
int value;
cin >> value;
setData(i,value);
}
}
Sorry I somehow I thought you wanted help with a runtime error but you want help with the compile errors.
The compile error in this part of the code
myArray::myArray(double* orig, int size) {
setSize(orig.getsize());
for(int i = 0; i<getSize();i++)
setData(i,orig.getData(i));
is specifically about the orig.getSize() part. orig is of type double* (pointer to double) and pointers do not have member functions only classes do which is why the compiler says: "which is non-class type double"
Actually there is no way in c++ to know from a pointer to how many elements it points but luckily your function already has a parameter size which i guess is meant to pass in the size of the orig array. So that line should be setSize(size);
Now two lines lower you get a similar error on setData(i,orig.getData(i)); orig is still a double* so it still doesn't have member functions. The correct way is setData(i, orig[i]);
EDIT:
BTW, i quick look through the rest of your code shows me that your setSize method doesn't allocate an array of appropriate size so you should fix that to.