C++ 不寻常的双重自由损坏错误(复制构造函数不起作用)
C++ Unusual double free corruption error (copy constructor doesn't work)
我是一名学生,我被要求 "replicate"(有点)矢量 class。显然,臭名昭著的 "double free corruption" 发生了。三个规则我一直在思考(可能不太好),我找不到错误。
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 向量使用复制构造函数,它不会给我错误)。
A.~Vettore();
B.~Vettore();
C.~Vettore();
这就是您的错误来源。初学者很少(如果有的话)需要显式调用对象的析构函数。当对象 A
、B
和 C
超出范围时,会自动调用析构函数。
在你的Add Component
_v=a;
_N=_N+1;
a=NULL;
delete [] a;
正确的实现方式是:
_N = _N + 1;
delete[] _v;
_v = a;
或者在调用对象的析构函数时,显式或隐式地删除_v
两次
我是一名学生,我被要求 "replicate"(有点)矢量 class。显然,臭名昭著的 "double free corruption" 发生了。三个规则我一直在思考(可能不太好),我找不到错误。
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 向量使用复制构造函数,它不会给我错误)。
A.~Vettore(); B.~Vettore(); C.~Vettore();
这就是您的错误来源。初学者很少(如果有的话)需要显式调用对象的析构函数。当对象 A
、B
和 C
超出范围时,会自动调用析构函数。
在你的Add Component
_v=a;
_N=_N+1;
a=NULL;
delete [] a;
正确的实现方式是:
_N = _N + 1;
delete[] _v;
_v = a;
或者在调用对象的析构函数时,显式或隐式地删除_v
两次