2012-11-19 16 views
0

我给了这个类的直方图,我动态地为我的班级分配内存。我遇到了析构函数问题。错误是:析构函数的问题 - 错误:表达式:_BLOCK_TYPE_IS_VALID_(pHead-> pBlockUse)

表达:_BLOCK_TYPE_IS_VALID_(pHead-> pBlockUse)

什么,我做错了什么?

histogram.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; 
} 
+0

'的for(int i = 0; I <2; i ++在)'这是不对的,应该是线,不2. –

回答

2

无论是构造函数初始化normalizedArray。这意味着在析构函数中对delete[] normalizedArray的调用将在单位指针上进行操作。要更正,请将每个构造函数中的normalizedArray初始化为NULL。在NULL指针上调用delete[](或delete)是安全的。

由于Histogram了动态分配的,你需要或者防止复制成员:

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

或正确执行拷贝构造函数和赋值操作符。看看是否有任何以下功能被称为HistogramWhat is The Rule of Three? 实例将被复制:

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; 
+0

这有可能是的成员函数之一(就像Normalized)那样做。但至少构造函数应该将normalizedArray初始化为NULL。 – john

+1

@john,它可能但很差,因为它意味着在构造之后的所有实例都是无效的,直到在对象上执行其他事情。 – hmjd

+0

我刚开始学习C++。暂时不能使用STL库。 – laura