0

これにクラスヒストグラムを付け、クラスに動的にメモリを割り当てています。デストラクタに問題があります。エラーは次のとおりです。

式:_BLOCK_TYPE_IS_VALID_(pHead-> pBlockUse)

私は何を間違っていますか?

ヒストグラム.h

 #ifndef HISTOGRAM_H
    #define HISTOGRAM_H
    #include<iostream>
    class Histogram
    {
    private:
        int** matrix;
        int lines;  
        double* normalizedArray;
        int *values;
        void SortMatrix();      
    public:
        Histogram(int elements[], int elementsNr);
        Histogram(int** matrix, int lines);
        void Normalize();
        void PrintNormalized();
        void PrintDenormalized();
        void PrintValues();
        void PrintNormalizedArray();
        int* GetValues() const {return values;} 
        double* GetNormalizedArray() const {return normalizedArray;}
        int GetLines() const {return lines;}
        double CalculateD1(Histogram histo);
        double CalculateD2(Histogram histo);
        double CalculateIntersection(Histogram hist);
        ~Histogram(){
        delete []matrix;
        delete []normalizedArray;
        delete []values;
        }
    };
    #endif
histogram.cpp

     #include<math.h>
#include"histogram.h"
using namespace std;
Histogram::Histogram(int** m, int l)
{
    lines=l;
    normalizedArray=NULL;
    values=NULL;
    matrix=new int*[lines];
    for(int i=0;i<lines;i++)
    {
        matrix[i]=new int[2];
    }
    for(int i=0;i<lines;i++)
    {
        matrix[i][0]=m[i][0];
        matrix[i][1]=m[i][1];
    }

    SortMatrix();
    //save the values
    values=new int[lines];
    for(int i=0;i<lines;i++)
    {
        values[i]=matrix[i][0];
    }
}

Histogram::Histogram(int elements[], int elementsNr)
{
    lines=0;
    normalizedArray=NULL;
    //initialize matrix : elementrNr lines and 2 columns
    matrix=new int*[elementsNr];
    for(int i=0;i<elementsNr;i++)
    {
        matrix[i]=new int[2];
        matrix[i][0]=INT_MIN;
        matrix[i][1]=INT_MIN;
    }
    //search each element from the array in the matrix
    bool found=false;
    for(int i=0;i<elementsNr;i++)
    {
        found=false;
        for(int j=0;j<elementsNr;j++)
        {
            //the element was found in the matrix ( on the first column )
            if(matrix[j][0] == elements[i])
            {
                matrix[j][1]++;
                found=true;
                break;
            }
        }
        if(!found)
        {
            matrix[lines][0]=elements[i];
            matrix[lines][1]=1;
            lines++;
        }
    }
    SortMatrix();
    //save the values
    values=new int[lines];
    for(int i=0;i<lines;i++)
    {
        values[i]=matrix[i][0];
    }

}
void Histogram::SortMatrix()
{

    for(int i=0;i<lines;i++)
    {
        for(int j=0;j<lines-1;j++)
        {
            if(matrix[j][0]>matrix[j+1][0])
            {
                int temp = matrix[j+1][0];
                matrix[j+1][0] = matrix[j][0];
                matrix[j][0] = temp;
            }
        }
    }
}

void Histogram::PrintDenormalized()
{
    for(int i=0;i<lines;i++)
    {
        cout<<matrix[i][0]<<" : " <<matrix[i][1]<<endl;
    }

}
void Histogram::PrintNormalized()
{
    for(int i=0;i<lines;i++)
    {
        cout<<matrix[i][0]<<" : "<<normalizedArray[i]<<endl;
    }
}

void Histogram::PrintValues()
{
    for(int i=0;i<lines;i++)
    {
        cout<<values[i]<<endl;
    }
}
void Histogram::PrintNormalizedArray()
{
    for(int i=0;i<lines;i++)
    {
        cout<<normalizedArray[i]<<endl;
    }
}

void Histogram::Normalize()
{
    int N=0;
    normalizedArray=new double[lines];
    for(int i=0;i<lines;i++)
    {
        N+=matrix[i][1];
    }
    for(int i=0;i<lines;i++)
    {
        normalizedArray[i]=static_cast<double>(matrix[i][1])/N;
    }
}

double Histogram::CalculateD1(Histogram histo)
{
    //the two histograms must have the same values
    int* values2 = histo.GetValues();
    int lines2 = histo.GetLines();
    if(lines!=lines2)
    {
        return -1;
    }
    for(int i=0;i<lines;i++)
    {
        if(values[i]!=values2[i])
        {
            return -1;
        }
    }

    //if we got this far the two histograms have the same values, so we can calculate the distance
    double* normalizedArray2=histo.GetNormalizedArray();
    double dist=0.0;
    for(int i=0;i<lines;i++)
    {
        dist +=  abs(normalizedArray[i]-normalizedArray2[i]);
    }
    return dist;
}

double Histogram::CalculateD2(Histogram histo)
{
    //the two histograms must have the same values
    int* values2 = histo.GetValues();
    int lines2 = histo.GetLines();
    if(lines!=lines2)
    {
        return -1;
    }
    for(int i=0;i<lines;i++)
    {
        if(values[i]!=values2[i])
        {
            return -1;
        }
    }

    //if we got this far the two histograms have the same values, so we can calculate the distance
    double* normalizedArray2=histo.GetNormalizedArray();
    double dist=0.0;
    for(int i=0;i<lines;i++)
    {
        dist +=  pow(normalizedArray[i]-normalizedArray2[i], 2);
    }
    return sqrt(dist);
}

double Histogram::CalculateIntersection(Histogram histo)
{
    //the two histograms must have the same values
    int* values2 = histo.GetValues();
    int lines2 = histo.GetLines();
    if(lines!=lines2)
    {
        return -1;
    }
    for(int i=0;i<lines;i++)
    {
        if(values[i]!=values2[i])
        {
            return -1;
        }
    }

    //if we got this far the two histograms have the same values, so we can calculate the intersection
    double* normalizedArray2=histo.GetNormalizedArray();
    double v1=0.0;
    double v2=0.0;
    for(int i=0;i<lines;i++)
    {
        v1 += normalizedArray[i] < normalizedArray2[i] ? normalizedArray[i] : normalizedArray2[i];
        v2 += normalizedArray[i];
    }
    return v1/v2;
}
4

1 に答える 1

2

どちらのコンストラクターも初期化しませんnormalizedArray。これはdelete[] normalizedArray、デストラクタでの呼び出しがユニタライズされたポインタで動作することを意味します。修正するにnormalizedArrayは、各コンストラクターでをに初期化しNULLます。delete[]ポインタで(またはdelete)を呼び出すのNULLは安全です。

動的に割り当てられたメンバーと同様Histogramに、コピーを防ぐ必要があります。

class Histogram
{
    Histogram(const Histogram&);
    Histogram& operator=(const Histogram&);
};

または、コピーコンストラクタと代入演算子を正しく実装します。三つのルールとは何ですか?を参照してください。次の関数のいずれかが呼び出されている場合、の インスタンスHistogram がコピーされます。

double CalculateD1(Histogram histo);         // Pass by const reference instead
double CalculateD2(Histogram histo);         // if the functions do not modify
double CalculateIntersection(Histogram hist) // their argument.

動的に割り当てられたメモリを持つクラスにコピーコンストラクタと代入演算子が実装されていない場合、クラスの2つのインスタンスは、コピー操作後に同じ動的に割り当てられたメモリを指すことになります。2つのインスタンスの一方が破棄されると、もう一方のインスタンスにはダングリングポインター(無効になったメモリへのポインター)が残ります。これらを使用しようとすると、未定義の動作になります。


これが演習でない場合は、std::vector<>代わりにsを使用してください。動的に割り当てられたメモリを処理します。

std::vector<std::vector<int>> matrix;
std::vector<double> normalizedArray;
std::vector<int> values;
于 2012-11-19T14:34:37.853 に答える