Estoy tratando de liberar memoria dinámica pero obtengo un error. Necesito ayuda para señalar qué parte de mi código está causando el error.

Tengo destructor para liberar dos matrices dinámicas. Al quitar el destructor no obtengo errores.

Error: _BLOCK_TYPE_IS_VALID (pHEAD-> nBlockUse)

Clase de puntuaciones:

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;
}

Principal:

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;
}
0
PLOW 15 feb. 2015 a las 12:21

2 respuestas

La mejor respuesta

Lo que está viendo es una doble eliminación. Un problema obvio es que está obteniendo un puntero al objeto s de la matriz asignada dinámicamente scoresArray aquí:

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

Luego llamas a delete[] en él:

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

Pero el objeto s también llama a delete[] en su destructor. Eso provocaría una doble eliminación.

Podría haber otros errores en el código además de este.

Tenga en cuenta que podría evitar trivialmente este problema si no usa la asignación dinámica de forma explícita, sino que confía en tipos como std::vector<double>.

1
juanchopanza 15 feb. 2015 a las 09:32

El problema es esta línea en Scores::setSort:

scoreSort = getScores();

getScores() devuelve scoresArray. Así que ahora scoreSort y scoresArray apuntan al mismo bloque asignado dinámicamente. Cuando intentas eliminar ambos, estás eliminando el mismo bloque dos veces.

En lugar de asignar los punteros, debe copiar el contenido de scoresArray en scoreSort, luego ordenar scoreSort.

0
Barmar 15 feb. 2015 a las 09:28