2012-11-19 48 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