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;
}
Related
Everything seems to be copying fine, but when I call array2.print(), it shows segmentation fault. What am I doing wrong?
#include <iostream>
#include <initializer_list>
template <typename T>
class DynamicArray
{
private:
const int GROWTH_FACTOR = 2;
const int INITIAL_CAPACITY = 5;
T *m_array;
int m_capacity; // Capacity of the array
int m_size; // Number of added elements
public:
DynamicArray(std::initializer_list<T> elements)
: m_size(elements.size())
, m_capacity(elements.size() * 2)
{
m_array = new T[m_capacity];
std::copy(elements.begin(), elements.end(), m_array);
}
DynamicArray()
: m_size(0)
, m_capacity(INITIAL_CAPACITY)
{
m_array = new T[m_capacity];
}
~DynamicArray()
{
delete[] m_array;
}
DynamicArray(const DynamicArray& other)
: GROWTH_FACTOR(other.GROWTH_FACTOR)
, INITIAL_CAPACITY(other.INITIAL_CAPACITY)
, m_capacity(other.m_capacity)
, m_size(other.m_size)
{
T *m_array = new T[m_capacity];
std::copy(other.m_array, other.m_array + m_size, m_array);
}
int size()
{
return m_size;
}
int capacity()
{
return m_capacity;
}
void resize()
{
int new_capacity = m_capacity * GROWTH_FACTOR;
m_capacity = new_capacity;
T *temp = new T[new_capacity];
std::copy(m_array, m_array + m_capacity, temp);
delete[] m_array;
m_array = temp;
}
void deleteAt(int pos)
{
for (int i = pos; i < m_size - 1; i++)
{
(*this)[i] = (*this)[i + 1];
}
m_size--;
}
void insertAt(T value, int pos)
{
if (m_capacity == m_size)
{
resize();
}
for (int i = m_size - 1; i >= pos; i--)
{
(*this)[i + 1] = (*this)[i];
}
m_size++;
(*this)[pos] = value;
}
void append(T value)
{
insertAt(value, m_size);
}
void print() {
for (int i = 0; i < m_size; i++)
{
std::cout << (*this)[i] << ", ";
}
std::cout << std::endl;
}
T& operator[](int index)
{
if (index < 0 || index > m_size - 1)
{
throw std::invalid_argument("Index out of range!");
}
return m_array[index];
}
};
int main()
{
DynamicArray<int> array = { 1, 2, 3, 4 };
DynamicArray<int> array2 = array;
array2.print();
return 0;
}
The error is here
T *m_array = new T[m_capacity];
It should be
m_array = new T[m_capacity];
By declaring a new variable called m_array you hid the class member variable that you wanted to assign to. The technical name for this is shadowing, a good compiler would warn you about this.
You redeclare m_array in the cctor, which shadows the class member.
I'm trying to work with dynamic arrays. When I try to overload the "=" operator it does not work. When debugging the file it doesn't execute the void function to overload the operator.
#include <iostream>
using namespace std;
class cppArray {
public:
cppArray(int size);
~cppArray();
int read(int index);
void write(int content, int index);
void operator=(cppArray& s);
int search(int target);
int size();
private:
int* myArray;
int arraySize;
};
cppArray::cppArray(int size) {
myArray = new int[size];
arraySize = size;
}
//delete the memory space assigned to myArray
cppArray::~cppArray() {
delete[] myArray;
myArray = 0;
}
int cppArray::read(int index) {
if (index < arraySize) {
return myArray[index];
}
else {
cout << "Out of range" << endl;
exit(1);
}
}
Here I'm trying to copy the content of the original array to an auxiliar one, and then redefine the size of the original array so I can add more content to the original array
void cppArray::write(int content, int index) {
if (index < arraySize) {
myArray[index] = content;
}
else {
cppArray auxArray(arraySize);
auxArray.myArray = myArray;
delete[] myArray;
arraySize = index + 1;
myArray = new int[arraySize];
myArray = auxArray.myArray;
myArray[index] = content;
}
}
I'm pretty sure this is wrong, but I can't figure out a way to overload it correctly
void cppArray::operator=(cppArray& s) {
delete[] s.myArray;
s.myArray = new int[arraySize];
for (int i = 0; i < arraySize; i++)
{
myArray[i] = s.myArray[i];
}
}
int cppArray::size() {
return arraySize;
}
int main(int argc, char** argv) {
cppArray dsArray(3);
dsArray.write(1, 0);
dsArray.write(2, 1);
dsArray.write(3, 2);
dsArray.write(4, 3);
for (int i = 0; i < dsArray.size(); i++) {
cout << dsArray.read(i) << "\t";
}
cout << endl;
return 0;
}```
Your implementation is almost correct, but you delete the wrong array. You should only modify *this object, and not s. Also, you should follow conventions, or people will be very surprised when using your class.
Here's corrected version:
//return *this - a very expected convention
cppArray& cppArray::operator=(const cppArray& s) {
// Make sure s is not modified ^^^^
if (this == &s) {
return *this; //protection against self writing, things would get bad if you did that
}
arraySize = s.arraySize; //copy size first
delete[] myArray; //delete array from this object
myArray = new int[arraySize]; //recreate array
for (int i = 0; i < arraySize; i++)
{
myArray[i] = s.myArray[i]; //no changes here
}
return *this;
}
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];
}
This is my class
class Process {
public:
Process();
void createBurstArray(int *bursts, int sizeOfArray);
void createIOArray(int *IO, int capacity);
int *burstArray;
int *ioArray;
int currentBurst;
int currentIO;
int currentState;
};
Process::Process()
{
}
void Process::createBurstArray(int *bursts, int capacity){
burstArray = new int[capacity];
burstArray = bursts;
};
void Process::createIOArray(int *IO, int capacity) {
ioArray = new int[capacity];
ioArray = IO;
for (int i = 0; i < capacity; i++)
};
void main(){
int processOneBursts[7] = { 12,10,15,11,9,10,11 };
int processOneIO[6] = { 44,52,21,42,31,77 };
Process processes[9];
Process one;
processes[0] = one;
one.createBurstArray(processOneBursts, 7);
one.createIOArray(processOneIO, 6);
}
When I try accessing the ioArray
one.ioArray[1]
I get the value stored in the ioArray at index 1, butw hen I try accessing the ioArra through my object array index it doesn't work:
for (int i = 0; i < 9; i++) {
cout << processes[i].ioArray[i] << endl;
}
What am I doing wrong?
#include <iostream>
using namespace std;
class Process {
public:
// Process();
void createBurstArray(int *bursts, int sizeOfArray);
void createIOArray(int *IO, int capacity);
int *burstArray;
int *ioArray;
int currentBurst;
int currentIO;
int currentState;
};
int main()
{
Process p[10];
for (int i = 0; i < 9; i++) {
p[i].ioArray = new int[1];
}
for (int i = 0; i < 9; i++) {
p[i].ioArray[0] = i;
}
for (int i = 0; i < 9; i++) {
cout << p[i].ioArray[0] << endl;
}
return 0;
}
This works, i think you didn't initialize the dynamic array.
You are object of the class with default constructor which means all the elements in the class will be uninitialized including the element int *ioArray;.
And you are trying to access ioArray in the for loop which is road set to segmentation fault.
To correct this, you must initialize the element before using them.
Also, Your below function is problematic.
void Process::createIOArray(int *IO, int capacity) {
ioArray = new int[capacity];
ioArray = IO;
}
This is a memory leak, since you have assign ioArray to IO ,new int[capacity] memory will not be freed.
Solution:
#include <iostream>
using namespace std;
class Process {
public:
Process();
void createBurstArray(int sizeOfArray);
void createIOArray(int capacity);
int *burstArray;
int *ioArray;
int currentBurst;
int currentIO;
int currentState;
// Don't forget to delete burstArray, ioArray in destructor.
};
void Process::createIOArray(int capacity) {
ioArray = new int[capacity];
};
void Process::createBurstArray(int sizeOfArray) {
burstArray = new int[sizeOfArray];
};
Process::Process(){
createIOArray(10);
createBurstArray(10);
// Similarly you have to initialize other members of the class
}
int main()
{
Process processes[9];
for (int i = 0; i < 9; i++) {
cout << processes[i].ioArray[i] << endl;
}
}
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?