C ++不寻常的双重免费损坏错误(复制构造函数不起作用)

时间:2016-01-03 00:02:17

标签: c++ debugging g++

我是学生,我被要求复制" (一种)矢量类。显然,臭名昭着的双重自由腐败"发生。我已经完成了三条规则(可能不太好),但我找不到错误。

Vettore.h

#ifndef vettore_h_
#define vettore_h_

#include <iostream>
#include <cmath>
#include <fstream>

class Vettore {

   protected:
      unsigned int _N;
      double * _v;
      void Quicksort(unsigned int primo, unsigned int ultimo);
      void Scambia (int a, int b);

   public:
      Vettore ();
      Vettore (int N);
      Vettore (int N, char* nomefile);
      Vettore (const Vettore& v);
      void SetComponent (int i, double x);
      void AddComponent (double x);
      double GetComponent (int i) const;
      void Print () const;
      void Print (char* nomefile) const;
      void Sort();
      int GetN() const;
      Vettore& operator=(const Vettore & vetty);
      ~Vettore();   
};

#endif

Vettore.c

#include "Vettore.h"

//Default Constructor

Vettore :: Vettore () {

   _N=0;
   _v=NULL;

};

//N Constructor

Vettore :: Vettore (int N) {

   _N=N;
   _v=new double [_N];

   for (int i=0; i<_N; i++)
      _v[i]=0;
};

//N file-taken constructor

Vettore :: Vettore (int N, char* nomefile) {

   _N=N;
   _v=new double [_N];

   std::ifstream input;
   input.open(nomefile);

   double dato;

   input>>dato;

   for(int i=0; i<N; i++){
      _v[i]=dato;
      input>>dato;
   };

   input.close();

};

//Copyconstructor

Vettore :: Vettore (const Vettore& V) {

   _N=V.GetN();

   _v=new double [_N];

   for(int i=0; i<_N; i++)
      _v[i]=V.GetComponent(i);


};

//Destructor

Vettore::~Vettore(){

   delete[] _v;

};

//Set Component

void Vettore :: SetComponent (int i, double x) {

   if (i>_N) {
      std::cout<<"errore!"<<std::endl;
      return ;
   };


   _v[i]=x;

};

//Get Component

double Vettore :: GetComponent (int i) const {

   if (i>_N){
      std::cout<<"errore!"<<std::endl;
      return 0;
   };

   return _v[i];
};

//Add Component 

void Vettore :: AddComponent (double x) {

   double* a=new double [_N+1];

   for(int i=0; i<_N; i++)
      a[i]=_v[i];

   a[_N]=x;

   _v=a;
   _N=_N+1;
   a=NULL;
   delete [] a;

};

//Print

void Vettore :: Print () const {

   std::cout<<"Il vettore ha: "<<_N<<" componenti."<<std::endl;

   for(int i=0; i<_N; i++)
      std::cout<<_v[i]<<std::endl;

};

//Print file

void Vettore :: Print (char* nomefile) const {
   std::ofstream output;
   output.open(nomefile);

   output<<_N;

   for(int i=0; i<_N; i++)
      output<<_v[i]<<std::endl;

   output.close();

};


//Get _N

int Vettore :: GetN () const {

   return _N;

};

//Operatore di Assegnazione

Vettore & Vettore::operator =(const Vettore& vetty){

   _N=vetty.GetN();
   _v=new double [_N];

   for(int n; n<_N; n++)
      _v[n]=vetty._v[n];

   return *this;
};



//Algoritmo Quicksort

void Vettore :: Sort (){
    Quicksort(0,GetN()-1);
};

void Vettore :: Quicksort (unsigned int primo, unsigned int ultimo) {

    if(ultimo-primo<=1){
       if (GetComponent(primo)>GetComponent(ultimo)) Scambia(primo, ultimo);
       return;
    }

    double pivot= GetComponent(int((primo+ultimo)/2));
    unsigned int basso= primo, alto=ultimo;
    while(basso < alto) {

        while (GetComponent(basso)<pivot) basso++;
        while (GetComponent(alto)>pivot) alto--;
        if(basso<alto) { Scambia(basso,alto); basso++;};
    };
    Quicksort(primo, basso-1);
    Quicksort(basso, ultimo);
};

void Vettore :: Scambia(int a, int b){

    double k;
    k=_v[a];
    _v[a]=_v[b];
    _v[b]=k;
};

主要例子

#include "Vettore.h"
#include <iostream>

using namespace std;

int main (int argv, char** argc) {

   Vettore A(10);

   Vettore B(10, argc[1]);

   Vettore C(B);

   C.SetComponent(2, 3);

   B.AddComponent(12.5);

   cout<<A.GetComponent(3)<<" "<<A.GetN()<<endl;

   B.Sort();

   B.Print();

   C.Print(argc[2]);

   A.~Vettore();
   B.~Vettore();
   C.~Vettore();

   return 0;
}

奇怪的是,析构函数被调用(我通过析构函数中的couts检查)三次;另一个奇怪的事情是我无法清楚地找到错误的来源,因为有时AddComponent会给我带来问题(但并非总是如此),而Copyconstructor似乎总是给我带来问题(换句话说,如果我消除了C向量初始化)使用copyconstructor,它不会给我一个错误)。

2 个答案:

答案 0 :(得分:2)

A.~Vettore();
B.~Vettore();
C.~Vettore();

这是您的错误来源。如果有的话,初学者很少需要显式调用对象的析构函数。当对象超出范围时,会自动为您的对象ABC调用析构函数。

答案 1 :(得分:1)

Add Component

_v=a;
_N=_N+1;
a=NULL;
delete [] a;

实现这一目标的正确方法是:

_N = _N + 1;
delete[] _v;
_v = a;

或者,当显式或隐式调用对象的析构函数时,您将删除_v两次。