This code is a class of arrays definition that uses dynamic memory to allocate memory. The command ArrayClass temp(_size); in operator+ method gives the following runtime error.
Unhandled exception at 0x7715C54F in ArrayClass.exe: Microsoft C++
exception: std::bad_array_new_length at memory location 0x0033FB10.
If we convert this command to ArrayClass *temp = new ArrayClass(_size), no error will be occured. But the new object temp that was allocated by new operator will not be deleted.
Does anyone have a solution?
#include <iostream>
using namespace std;
class ArrayClass {
private:
int _size;
float* _ar;
public:
ArrayClass(const int& size) {
_size = size;
_ar = new float[_size];
}
~ArrayClass() {
delete[]_ar;
}
const ArrayClass& operator=(const ArrayClass& RightOperand) {
if (this != &RightOperand) {
if (this->_size != RightOperand._size) {
delete[] this->_ar;
this->_size = RightOperand._size;
this->_ar = new float[this->_size];
}
for (int i = 0; i < RightOperand._size; i++)
{
this->_ar[i] = RightOperand._ar[i];
}
}
return *this;
}
const ArrayClass& operator+(const ArrayClass& RightOperand) {
//*this+RightOperand
if (this->_size != RightOperand._size) {
cout << "different Size";
exit(1);
}
ArrayClass temp(_size);
for (int i = 0; i < _size; i++)
{
temp._ar[i] = this->_ar[i] + RightOperand._ar[i];
}
return temp;
}
};
int main() {
ArrayClass x(5), y(5), z(5);
x = y;
z= x + y;
return 0;
}
Related
My string-dynamic-array.cpp file
#include <iostream>
#include <string>
class DynamicArray
{
public:
DynamicArray()
: mCapacity(1), mNumberOfElements(0)
{
mArray = new std::string[mCapacity];
}
DynamicArray(int size)
: mCapacity(size), mNumberOfElements(0)
{
mArray = new std::string[mCapacity];
}
DynamicArray(const DynamicArray& array)
: mCapacity(array.getCapacity()), mNumberOfElements(array.length())
{
mArray = new std::string[mCapacity];
for (size_t i = 0; i < mCapacity; ++i)
{
mArray[i] = array.get(i);
}
}
~DynamicArray()
{
delete[] mArray;
}
void add(std::string element)
{
if (mNumberOfElements >= mCapacity)
{
expand();
}
mArray[mNumberOfElements++] = element;
}
std::string get(int index) const
{
if (index > mNumberOfElements)
{
std::string exception = std::to_string(index) + " index is out of bounds.";
std::cout << exception;
return std::string();
}
if (index < 0)
{
if (mNumberOfElements + index < 0)
{
std::string exception = std::to_string(index) + " index result in " + std::to_string(mNumberOfElements + index) + " which is out of bounds.\n";
std::cout << exception;
return std::string();
}
return mArray[mNumberOfElements + index];
}
return mArray[index];
}
int length() const
{
return mNumberOfElements;
}
int getCapacity() const
{
return mCapacity;
}
private:
int mCapacity;
int mNumberOfElements;
std::string* mArray;
void initialize(int from)
{
for (size_t i = from; i < mCapacity; ++i)
{
mArray[i] = std::string();
}
}
void expand()
{
mCapacity *= 2;
std::string* temporaryArray = new std::string[mCapacity];
for (size_t i = 0; i < mCapacity; ++i)
{
temporaryArray[i] = mArray[i];
}
delete[] mArray;
mArray = temporaryArray;
initialize(mNumberOfElements);
}
};
int main()
{
DynamicArray strings;
strings.add("Hello");
strings.add("World");
for (size_t i = 0; i < strings.length(); ++i)
{
std::cout << strings.get(i) << std::endl;
}
}
My output
$ clang++ tests/string-dynamic-array.cpp -o tests/string-dynamic-array && ./tests/string-dynamic-array
[1] 14950 segmentation fault (core dumped) ./tests/string-dynamic-array
I get a segmentation fault.
The issue as far as I've found is in the code where I expand the array, in the expand() function. I think it's in the for loop because the index of for loop is out of bounds of the original array.
I've tried this with int, it seems to work fine. How can I do this with strings?
As commented by UnholySheep.
I changed my expand function a bit so the loop only runs till the size of the old array.
Updated expand function:
void expand()
{
mCapacity *= 2;
std::string* temporaryArray = new std::string[mCapacity];
for (size_t i = 0; i < mNumberOfElements; ++i)
{
temporaryArray[i] = mArray[i];
}
delete[] mArray;
mArray = temporaryArray;
initialize(mNumberOfElements);
}
In “expand” method you have deleted mArray, then, you copied the temporaryArray to it, while as far as I know, mArray’s handle is not valid anymore. You need to pass temporaryArray‘s handle to mArray so you could use it as a new expanded array.
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 creating a dynamic array class and I'm new to c++. I'm having trouble overloading the addition operator to add a string to an object. When I do try to add a string, nothing shows up on the compile screen. I also added my copy constructor, destructor, overloaded assignment operator, and overloaded ostream operator just in case any of those were the issue. Thank you so much for the help!!
DynamicStringArray::~DynamicStringArray()
{
delete[] dynamic_Array;
dynamic_Array = NULL;
}
DynamicStringArray::DynamicStringArray(const DynamicStringArray& first)
{
size = first.returns_Size();
dynamic_Array = new string[size];
for (int n = 0; n < size; n++)
{
dynamic_Array[n] = first.get_Entry(n);
}
}
void DynamicStringArray::operator =(const DynamicStringArray& first)
{
this->size = first.returns_Size();
this->dynamic_Array = new string[size];
for (int i = 0; i < this->size; i++)
{
this->dynamic_Array[i] = first.get_Entry(i);
}
}
ostream& operator <<(ostream& out, const DynamicStringArray& first) //nonmember requires 2 arguments
{
for (int i = 0; i < first.size; i++)
{
out << first.dynamic_Array[i] << endl;
}
return out;
}
void DynamicStringArray::add_Entry(string a)
{
string* Temp_Array = dynamic_Array; //old array
dynamic_Array = new string[size + 1]; //new array
for (int i= 0; i < size; i++) //copy old string values to temp array
{
dynamic_Array[i] = Temp_Array[i];
}
dynamic_Array[size] = a; //puts string a into last position of new array
delete[]Temp_Array; //free memory space
size++;
}
DynamicStringArray DynamicStringArray::operator +(const string& a)
{
DynamicStringArray added;
added.add_Entry(a);
return added;
}
int main()
{
DynamicStringArray fav_Foods;
fav_Foods.add_Entry("pasta");
fav_Foods.add_Entry("sushi");
fav_Foods + "Burgers";
cout << fav_Foods << endl;
}
DynamicStringArray DynamicStringArray::operator +(const string& a)
{
DynamicStringArray added;
added.add_Entry(a);
return added;
}
Why do you think you need to create a new DynamicStringArray added?
Simply call add_Entry(a) on the current instance. Also, operator+() should return a reference to the instance it is called upon:
DynamicStringArray& DynamicStringArray::operator+(string const &a)
{
add_Entry(a);
return *this;
}
I just came across a strange problem. I will paste the full code below:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
// declare a base class
class Base
{
public:
Base();
Base(int n, int arr[2]);
Base(const Base &base);
Base &operator=(const Base &rhs);
int getSize() const;
int *getA() const;
~Base();
private:
int *a;
int size;
};
class Case
{
public:
Case();
Case(int n, int arr[2]);
Case(const Case &rhs);
Case &operator=(const Case &rhs);
int getSize() const;
int *getA() const;
~Case();
private:
int *a;
int size;
};
class Dase
{
public:
Dase();
Dase(int bSize, int barr[2], int cSize, int carr[2]);
Dase(const Dase &dase);
Dase &operator=(const Dase &rhs);
Base getB() const;
Case getC() const;
~Dase();
private:
Base b;
Case c;
};
// implementation
Base::Base() : size(0)
{
a = NULL;
}
Base::Base(int n, int arr[2]) : size(n)
{
a = new int[n];
for (int i = 0; i < size; i++)
a[i] = arr[i];
}
Base::Base(const Base &base)
{
size = base.getSize();
a = new int[size];
for (int i = 0; i < size; i++)
a[i] = base.getA()[i];
}
Base &Base::operator=(const Base &rhs)
{
if (this == &rhs)
return *this;
size = rhs.getSize();
delete[] a;
a = new int[size];
for (int i = 0; i < size; i++)
a[i] = rhs.getA()[i];
return *this;
}
int *Base::getA() const
{
return a;
}
int Base::getSize() const
{
return size;
}
Base::~Base()
{
delete[] a;
}
Case::Case() : size(0)
{
a = NULL;
}
Case::Case(int n, int arr[2]) : size(n)
{
a = new int[n];
for (int i = 0; i < size; i++)
a[i] = arr[i];
}
Case::Case(const Case &rhs)
{
size = rhs.getSize();
a = new int[size];
for (int i = 0; i < size; i++)
a[i] = rhs.getA()[i];
}
Case &Case::operator=(const Case &rhs)
{
if (this == &rhs)
return *this;
size = rhs.getSize();
delete[] a;
a = new int[size];
for (int i = 0; i < size; i++)
a[i] = rhs.getA()[i];
return *this;
}
int *Case::getA() const
{
return a;
}
int Case::getSize() const
{
return size;
}
Case::~Case()
{
delete[] a;
}
// implement class Dase
Dase::Dase() : b(Base()), c(Case())
{
// delebrately left empty
}
Dase::Dase(int bSize, int barr[2], int cSize, int carr[2])
{
b = Base(bSize, barr);
c = Case(cSize, carr);
}
Dase::Dase(const Dase &dase)
{
b = dase.getB();
c = dase.getC();
}
Dase &Dase::operator=(const Dase &rhs)
{
if (this == &rhs)
return *this;
b = rhs.getB();
c = rhs.getC();
return *this;
}
Base Dase::getB() const
{
return b;
}
Case Dase::getC() const
{
return c;
}
Dase::~Dase()
{
b.~Base();
c.~Case();
}
In the above code, I defined 3 classes: Base, Case, Dase. I included their declarations and implementations. The following is the main code:
#include "classes.h"
int main()
{
int arr[2] = {1, 2};
int brr[2] = {3, 4};
Dase d1(2, arr, 2, brr);
Dase d2;
d2 = d1;
}
This is a very simple main code, but I got "double free or corruption (fasttop)" error in the runtime.
I noticed that when I deleted the destructor in the class Dase, this problem went away. What shall I do to fix this problem if I want to keep the destructor for Dase? Shall I change its implementation?
Thank you!
You should not call destructors explicitly. It's done automatically.
So, replace
Dase::~Dase()
{
b.~Base();
c.~Case();
}
with
Dase::~Dase()
{
}
I have problem only with the push_back function, the compiler said:
CRT detected that the application wrote to memory after end of heap buffer
I want to make a push_back function, that adds a new element to the vector's end.
#pragma once
#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstdlib>
class tomb {
private:
double *adat;
int szam;
public:
tomb(){
adat = NULL;
szam = 0;
}
int meret()const {
return szam;
}
~tomb() {
delete[] adat;
}
double & operator[](int n) {
return adat[n];
}
const double & operator[](int n)const {
return adat[n];
}
void push_back(const double &a) {
double *tmp;
int pos = szam + 1;
tmp = new double[szam+1];
for (int i = 0; i < szam; i++)
{
tmp[i] = adat[i];
}
tmp[pos] = a;
delete[] adat;
adat = tmp;
++szam;
}
void Kiir()const {
for (int i = 0; i < szam; i++)
{
std::cout << adat[i] << "\n";
}
}
};
pos should be szam not szam+1. You are willing to insert at the last position, which in 0-based indexing is n-1.
The problem is in this line:
tmp[pos] = a;
Since pos is initialized to szam + 1, that is equivalent to:
tmp[szam + 1] = a;
which is one out of the array limit.
The solution is to get rid of pos altogether and just do:
tmp[szam] = a;
BTW, your class is using the default copy constructor and assignment operator, and those will not work properly. You should really do something about that.