0

I have a class and i keep getting some error from the destructor. This is the clas:

#pragma once
class Number
{
    int bas;
    char* val;
public:
    Number(const char* value, int base); 
    Number(const Number& x);
    ~Number();
    void SwitchBase(int newBase);
    void Print();
    int  GetDigitsCount();
    int  GetBase(); 
};

This is the cpp file:

#include "Number.h"
#include <iostream>
Number::Number(const char* value, int base)
{
    int a = -1;
    do
    {
        a++;
    } while (value[a] != '\0');
    val = new char[a + 1];
    for (int i = 0; i <= a; i++)
        val[i] = value[i];
    bas = base;
}

Number::Number(const Number& x)
{
    int a = -1;
    bas = x.bas;
    do
    {
        a++;
    } while (x.val[a] != '\0');
    delete[]val;
    val = new char[a + 1];
    int i;
    for (i = 0; i <= a; i++)
        val[i] = x.val[i];
}
Number::~Number()
{
    delete[]val;
}
void Number::Print()
{
    std::cout << "Numarul este: " << val<< std::endl << "Baza este: " << bas<<std::endl;
}
int Number:: GetDigitsCount()
{
    int l = 0;
    do
    {
        l++;
    } while (val[l] != '\0');
    return l;
}

This is the main:

int main()
{
    Number x("123", 10),y("111",10),z("0",10);
    z = y;
    z.Print();
}

I keep getting this error: Invalid address specified to RtlValidateHeap( 010C0000, 010C8DD8 ) If i do this change in main it works properly but it is not really what I want...

int main()
{
    Number x("123", 10),y("111",10);
    Number z = y;
    z.Print();
}

How can I solve this? I can't figure it out...

Fisher
  • 3
  • 4

2 Answers2

2

Your Number class is missing an assignment operator. Since you use the assignment operator in main the default assignment operator will cause a double delete when you exit main and this explains the error.

It also explains why the error goes away when you change main to use the copy constructor instead of the assignment operator.

You should look at the copy and swap idiom to show how to easily and efficiently implement copy constructors and assignment operators.

Alternatively you could also use std::string instead of manually allocating memory. This would eliminate the need to write a destructor, copy constructor and assignment operator. That's the best solution.

john
  • 71,156
  • 4
  • 49
  • 68
2

This is an example of how code may look like using std::string:

#include <iostream>
#include <string>

class Number
{
    int bas;
    std::string val;
public:
    Number(std::string, int base); 
    Number(const Number& number);
    Number& operator= (const Number& number);
    ~Number()=default;
    void Print();
    int  GetDigitsCount();
};


Number::Number(std::string value, int base)
{
    val=value;
    bas=base;
}

Number::Number(const Number& number)
{
    val=number.val;
    bas=number.bas;
}

Number& Number::operator= (const Number& number)
{
    val=number.val;
    bas=number.bas;
    return *this;
}

void Number::Print()
{
    std::cout << "Numarul este: " << val<< std::endl << "Baza este: " << bas<<std::endl;
}
int Number:: GetDigitsCount()
{
    return val.size();
}

int main()
{
    Number x("123", 10),y("111",10),z("0",10);
    Number k(y);
    k.Print();
}
Jose
  • 3,004
  • 1
  • 14
  • 22
  • If you use `std::string` then there is no need to write explicit copy constructors and assignment operators. That's one of the main points. – john Mar 21 '20 at 11:02
  • Thanks, I had to do it without string libraries, that's why i didn't use them. – Fisher Mar 27 '20 at 11:46