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()
{
}
Related
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;
}
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;
}
Compilation error is:
'initializing': cannot convert from 'int' to 'Money'
File: genericarray.h
Line: 13
This is my main function
int main()
{
genericArray<Money>m3(5);
Money d(-1, 89);
Money a(10, 5);
Money b(10, 5);
Money c(43, 7);
Money k(50, 6);
Money m(10, 20);
Money bonus(5, 0);
m3.elements[0] = a;
m3.elements[1] = b;
m3.elements[2] = c;
m3.elements[3] = k;
m3.elements[4] = m;
m3.total = m3.sum();
m2.total = m2.sum();
m1.total = m1.sum();
return 0;
}
This is my Assignment operator overloading of Money class and Money class itself
class Money
{
private:
int lira;
int kurus;
public:
Money() { lira = 0; kurus = 0; }
Money(int a, int b);
~Money() {}
void operator=(const Money& money2) { this->lira = money2.lira; this->kurus = money2.kurus; }
void operator=(int l) { this->lira = l; this->kurus = 0; }
This is my genericArray class with sum() function
template <class Type>
class genericArray
{
private:
int size;
public:
Type* elements;
Type total;
Type sum()
{
Type sumAll = 0;
for (int i = 0; i < size; i++)
{
sumAll += elements[i];
}
if (sumAll > 100)
sumAll += 5;
return sumAll;
}
genericArray() { elements = NULL; size = 0; }
genericArray(int arrSize) { elements = new Type[arrSize]; size = arrSize; }
~genericArray() { delete[] elements; }
};
Writing a new constructor with a single int parameter solved the problem:
Money(const int a)
{
if (a < 0) throw "The amount of money can not be below zero!";
this->lira = a;
this->kurus = 0;
}
The point is that
Type sumAll = 0;
calls only the constructor which takes only 1 int instead of calling the default constructor and the assignment operator.
I am trying to add a Complex number, represented in Complex class to an array of complex.
#pragma once
class Complex
{
private:
int re, im;
public:
Complex() {};
Complex(int a, int b) { re = a; im = b; }
Complex(const Complex &);
Complex& operator=(const Complex &);
//operators overloading
bool operator==(Complex);
//member function
void print();
};
class Multime
{
private:
Complex *array;
static int nrElem;
int dim;
public:
Multime();
Multime(int a) { dim = a; nrElem = 0; array = new Complex[dim]; }
~Multime();
//Operators overloading
Multime& operator += (Complex b);
Multime& operator =(const Multime &);
//member function
void print();
};
Functions.cpp
#include <iostream>
#include "Multime.h"
using namespace std;
Complex::Complex(const Complex &a)
{
re = a.re;
im = a.im;
}
Complex& Complex::operator= (const Complex&a)
{
re = a.re;
im = a.im;
return *this;
}
void Complex::print()
{
cout << re << "+" << im << "i" << endl;
}
bool Complex::operator==(const Complex a)
{
return (re == a.re && im == a.im);
}
//Multime
//
Multime::Multime()
{
dim = 0;
nrElem = 0;
array = nullptr;
}
Multime::~Multime()
{
if (nullptr != array)
{
delete[] array;
}
}
void Multime::print()
{
for (int i = 0; i < nrElem; ++i)
{
array[i].print();
}
cout << endl;
}
Multime& Multime::operator +=(Complex a)
{
int g = 0;
if (nrElem < dim)
{
for (int i = 0; i < nrElem; ++i)
{
if (array[i] == a)
{
g = 1;
}
}
}
if (!g) //Element not found, can insert
{
array[nrElem++] = a;
}
return *this;
}
Multime& Multime::operator =(const Multime & a)
{
dim = a.dim;
array = new Complex[dim];
for (int i = 0; i < nrElem; ++i)
{
array[i] = a.array[i];
}
return *this;
}
In main I wrote the initialization for the static int Multime::nrElem = 0; after preprocessor directivesand and in main(void):
Multime a[50];
Complex f(2, 5), b(1, 3), c(5, 4);
a+=f;
but I get the error: binary '+=': no global operator found.I don't wanna use a friend function for +. I tried to create separate functions for + and = but the error is still there.
LE. The problem was in main a it's an array of Multime. Correct one, using initialization constructor: Multime a(50);
a+=f;
is not valid since a is an array of Multime, not an object of type Multime.
If you want to use the operator+= on one object, you could use
a[0] += f;
If you want to use it for all the objects in the array, use a loop.
for ( auto& item : a )
{
item += f;
}
I don't know, which is not correct, the copy constructor or the operator=. I tested with two "tombs", and the printer is working, but at the end of the program the compiler said "debug assertion failed".
#pragma once
#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstdlib>
class tomb {
private:
double *adat;
int szam;
public:
tomb(){
adat = NULL;
szam = 0;
}
tomb(const tomb &u) {
adat = u.adat;
szam = u.szam;
};
int meret()const {
return szam;
}
~tomb() {
delete[] adat;
}
double & operator[](int n) {
return adat[n];
}
const double & operator[](int n)const {
return adat[n];
}
const tomb &operator=(const tomb &a) {
adat = a.adat;
szam = a.szam;
return *this;
}
tomb elso_valahany(int n) {
}
void push_back(const double &a) {
double *tmp;
tmp = new double[szam+1];
for (int i = 0; i < szam; i++)
{
tmp[i] = adat[i];
}
tmp[szam] = a;
delete[] adat;
adat = tmp;
++szam;
}
void Kiir()const {
for (int i = 0; i < szam; i++)
{
std::cout << adat[i] << "\n";
}
}
};
As per the comments, I'll show you how to do a deep copy: every time you copy the class, you will not be copying just the pointer to the data, but the whole vector instead.
Also, for the sake of simplicity, I'll use std::vector:
#pragma once
#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstdlib>
#include <vector>
class tomb {
private:
std::vector<double> adat;
int szam;
public:
tomb(){
szam = 0;
}
tomb(const tomb &u) : adat(u.adat), szam(u.szam)
{
adat = u.adat;
szam = u.szam;
};
int meret() const {
return szam;
}
~tomb() {
}
double & operator[](int n) const {
return adat[n];
}
const double & operator[](int n) const {
return adat[n];
}
tomb& operator=(const tomb &a) {
adat = a.adat;
szam = a.szam;
return *this;
}
tomb elso_valahany(int n) {
}
void push_back(const double &a) {
adat.push_back(a);
++szam;
}
void Kiir()const {
for (int i = 0; i < szam; i++)
{
std::cout << adat[i] << "\n";
}
}
I haven't compiled/tested, but it should be fine now, as the memory management is done by std copy constructors!