Al Bundy
Al Bundy

Reputation: 683

Delete[] within destructor, allocating within constructor

I allocate memory in constructor and then do delete[] in destructor but I get _Block_Type_Is_Valid (pHead->nBlockUse)" Error. I came across the rule of three and got along with that. In my program I just have one instance and I am using nor Copy Constructor neither Copy Assignment Operator so I thought that I just need explicitly declared destructor. In constructor I am copying the values of char array and I cant get the idea what is wrong. Here is short listing of program code. Header:

class CTest
{
private:
    char *TestTable;
    int TestTableLength;
    std::chrono::steady_clock::time_point StartPoint;
    std::chrono::steady_clock::time_point EndPoint;
    std::chrono::steady_clock::time_point CheckPoint;
    std::chrono::system_clock::duration d;
public:
    CTest(char *SignTable);
    ~CTest();
    void NewCombination();
    bool AskToPlay();
    bool AskForNewCombination();
    void Play();
};

Source:

CTest::CTest(char *SignTable)
{
    int SignTableLength = 0;
    for (int i = 0; *(SignTable + i) != '\0'; i++)
    {
        SignTableLength++;
    }
    TestTableLength = SignTableLength ;
    TestTable = new char[TestTableLength];
    for (int i = 0; *(SignTable + i) != '\0'; i++)
    {
        *(TestTable + i) = *(SignTable + i);
    }
}


CTest::~CTest()
{
    delete[] TestTable;
}

void CTest::NewCombination()
{
    int tmpInt; 
    char tmpChar;
    if (TestTable != NULL)
    {
        for (int i = 0; i < TestTableLength - 1; i++)
        {
            tmpInt = rand() % (TestTableLength - i);
            tmpChar = TestTable[TestTableLength - 1 - i];
            TestTable[TestTableLength - 1 - i] = TestTable[tmpInt];
            TestTable[tmpInt] = tmpChar;
        }
    }
}

bool CTest::AskToPlay()
{
    char play;
    std::cout << "Do you want to play again ?" << std::endl << "If yes press 'y' else  press something else" << std::endl;
    std::cin >> play;
    if (play == 'y') return true;
    else return false;
};

bool CTest::AskForNewCombination()
{
    char newcom;
    std::cout << "Do you want me to create new combination?" << std::endl << "If yes press 'y' else press something else" << std::endl;
    std::cin >> newcom;
    if (newcom == 'y') return true;
    else return false;
};

void CTest::Play()
{
    StartPoint = std::chrono::steady_clock::now();
    CheckPoint = std::chrono::steady_clock::now();
    std::cout << "3\t";
    d = CheckPoint - StartPoint;
    while (std::chrono::duration_cast<std::chrono::milliseconds>(d).count() < 1000)
    {
        CheckPoint = std::chrono::steady_clock::now();
        d = CheckPoint - StartPoint;
    }
    std::cout << "2\t";
    while (std::chrono::duration_cast<std::chrono::milliseconds>(d).count() < 2000)
    {
        CheckPoint = std::chrono::steady_clock::now();
        d = CheckPoint - StartPoint;
    }
    std::cout << "1" << std::endl;
    while (std::chrono::duration_cast<std::chrono::milliseconds>(d).count() < 3000)
    {
        CheckPoint = std::chrono::steady_clock::now();
        d = CheckPoint - StartPoint;
    }
    std::cout << "START!" << std::endl;
    StartPoint = std::chrono::steady_clock::now();
    for (int i = 0; i < (TestTableLength ) ; i++)
    {
        std::cout << *(TestTable + i) << " ";
    }
};

Main:

char Signs[] = { '1', '2', '3', '4', '5', '6', 'q', 'w', 'e', 'r', 'f', 'g' };
CTest Test(Signs);

int _tmain(int argc, _TCHAR* argv[])
{
    srand(time(NULL));
    while (Test.AskToPlay())
    {
        if (Test.AskForNewCombination()) Test.NewCombination();
        Test.Play();
    }

    Test.~CTest();
    return 0;
}

Upvotes: 0

Views: 138

Answers (1)

SomeWittyUsername
SomeWittyUsername

Reputation: 18368

You're calling the destructor explicitly at the end of main. It shouldn't be done, the destructor is called automatically at the program end (i.e. when your global Test object goes out of scope). Your explicitly called destructor frees the allocated memory and upon program termination the destructor is called again, attempting to free the memory again, causing the observed failure.

Upvotes: 2

Related Questions