Search code examples
c++dynamic-memory-allocationdynamic-variables

free dynamic array memory error: _BLOCK_TYPE_IS_VALID


I'm trying to free dynamic memory but I'm getting an error. I need some help pointing out which part of my code is causing the error.

I have destructor to free two dynamic arrays. Removing the destructor I get not errors.

Error: _BLOCK_TYPE_IS_VALID(pHEAD->nBlockUse)

Scores Class:

class Scores
{
private:
    int numOfTest;
    double *scoresArray = nullptr;
    double scoreAvg;
    double *scoreSort = nullptr;
public:
    Scores(int);
    ~Scores();
    void setNumOfTest();
    int getNumOFTest();
    void setScores();
    double* getScores();
    void setSort();
    double* getSort();
    void setScoreAvg();
    double getScoreAvg();
};

Scores::Scores(int num)
{
    scoresArray = new double [num];
    scoreSort = new double[num];
    numOfTest = num;
}

Scores::~Scores()
{
    delete [] scoresArray;
    delete [] scoreSort;
    scoresArray = nullptr;
    scoreSort = nullptr;
}



void Scores::setNumOfTest()
{
    // Verify number of test scores is positive
    while (numOfTest <= 0)
    {
        cout << "The number of test need to be postive." << endl;
        cout << "Enter another number: ";
        cin >> numOfTest;
    }
}

int Scores::getNumOFTest()
{
    return numOfTest;
}

void Scores::setScores()
{
    double scores;
    int size = getNumOFTest();
    //scoresArray = new double[size];

    for (int i = 0; i < numOfTest; i++)
    {
        cout << "Enter test score " << i + 1 << ": ";
        cin >> scores;

        // Verify if score enter is positive
        while (scores < 0)
        {
            cout << "Negative scores are not allowed." << endl;
            cout << "Enter another score for this test: ";
            cin >> scores;
        }

        scoresArray[i] = scores;
    }
}

double* Scores::getScores()
{
    //double *sa = scoresArray; 
    //return sa;
    return scoresArray;
}

void Scores::setSort()
{
    int size = getNumOFTest();
    //scoreSort = new double[size];
    scoreSort = getScores();

    for (int i = 0; i < size; i++)
    {
        int smallPos = i;
        double smallest = scoreSort[smallPos];

        for (int j = i + 1; j < size; j++)
        {
            if (scoreSort[j] < scoreSort[smallPos])
            {
                smallPos = j;
                smallest = scoreSort[smallPos];
            }
        }

        scoreSort[smallPos] = scoreSort[i];
        scoreSort[i] = smallest;
    }
}

double* Scores::getSort()
{
    //double *ss = scoreSort;
    //return ss;
    return scoreSort;
}

void Scores::setScoreAvg()
{
    int size = getNumOFTest();

    for (int i = 0; i < size; i++)
    {
        scoreAvg += scoresArray[i];
    }

    scoreAvg /= size;
}

double Scores::getScoreAvg()
{
    return scoreAvg;
}

Main:

int main()
{
    int numOfTest;

    cout << "How many test scores will you enter" << endl;
    cin >> numOfTest;

    Scores s(numOfTest);

    s.setNumOfTest();
    s.setScores();
    s.setSort();
    s.setScoreAvg();

    double y = s.getScoreAvg();
    double *x = nullptr;
    x = new double[numOfTest];
    x = s.getSort();

    cout << "sort" << endl;
    for (int i = 0; i < numOfTest; i++)
    {
        cout << x[i] << "\n";
    }

    cout << "avg" << endl;
    cout << y;
    delete[] x;
    x = nullptr;
    //s.Scores1();

    return 0;
}

Solution

  • What you are seeing is a double delete. One obvious problem is that you are getting a pointer to object s's dynamically allocated array scoresArray here:

    x = s.getSort(); // also leaks memory previously pointed at by x
    

    then you call delete[] on it:

    delete[] x; // calls delete[] on s.scoresArray
    

    But the s object also calls delete[] on it in its destructor. That would cause a double deletion.

    There could be other errors in the code besides this one.

    Note that you could trivially avoid this problem by not using dynamic allocation explicitly, but relying on types such as std::vector<double> instead.