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.

如果没有为具有动态分配内存的类实现复制构造函数和赋值运算符,则该类的两个实例将在复制操作后最终指向同一个动态分配的内存。当两个实例之一被破坏时,它会为另一个实例留下悬空指针(指向不再有效的内存的指针)。任何使用这些的尝试都是未定义的行为


如果这不是练习,请改用std::vector<>s。它为您处理动态分配的内存:

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