why destructor function called twice

D

David

Hi all,
something wrong with my code, it seems that the destructor function
has been called twice. I don't know why.here is my codes
Fixture.h
#ifndef _FIXTURE_H
#define _FIXTURE_H

#include <string>
#include <map>
#include <list>
#include <vector>
#include <utility>
#include <algorithm>

using namespace std;

class Fixture
{
protected:
string fixturename;
vector<string>faces
map<string,vector<string> > points;
map<string,string>locators;
public:
Fixture();
Fixture(const Fixture &fix);
~Fixture();
void AddLocateFace(const string &face);
void AddLocatePoint(const string &face,const string &point);
void AddLocator(const string &point,const string &locator);
};

Fixture.cpp
#include "Fixture.h"
#include "PrjError.h"

#include <iostream>


Fixture::Fixture()
{
fixturename="";
}
Fixture::Fixture(const Fixture &fix)
{
fixturename=fix.fixturename;
faces=fix.faces;
points=fix.points;
locators=fix.locators;
}
Fixture::~Fixture()
{

}

void Fixture::AddLocateFace(const string &face)
{
vector<string>::iterator ii;
int found=0;
for(ii=faces.begin();ii!=faces.end();ii++)
{
if(*ii==face)
{
found=1;
break;
}
}
if(found==0)
faces.push_back(face);
else
throw PrjError::prjError(PrjError::ERR_ALREADY_EXIST);
}

void Fixture::AddLocatePoint(const string &face,const string &point)
{
map<string,vector<string> >::iterator ii;
vector<string> temp;
vector<string>::iterator kk;
kk=find(faces.begin(),faces.end(),face);
if(kk==faces.end())
throw PrjError::prjError(PrjError::ERR_NOT_FIND);
ii=points.find(face);
if(ii==points.end())
{
pair<map<string,vector<string> >::iterator,bool> p;
temp.push_back(point);
map<string,vector<string> >::value_type newpoint(face,temp);
p=points.insert(newpoint);
if(p.second==false)
throw PrjError::prjError(PrjError::ERR_INSERT_NEW);
ii=p.first;
}
else
{
kk=find(ii->second.begin(),ii->second.end(),point);
if(kk!=ii->second.end())
throw PrjError::prjError(PrjError::ERR_ALREADY_EXIST);
ii->second.push_back(point);
}
}

void Fixture::AddLocator(const string &point,const string &locator)
{
map<string,string>::iterator ii;
map<string,vector<string> >::iterator jj;
vector<string>::iterator kk;
int found=0;

//find the point
for(jj=points.begin();jj!=points.end();jj++)
{
kk=find(jj->second.begin(),jj->second.end(),point);
if(kk!=jj->second.end())
{
found=1;
break;
}
}

if(found==0)
throw PrjError::prjError(PrjError::ERR_NOT_FIND);
ii=locators.find(point);
if(ii!=locators.end())
throw PrjError::prjError(PrjError::ERR_ALREADY_EXIST);

pair<map<string,string>::iterator,bool> p;
map<string,string>::value_type newlocator(point,locator);
p=locators.insert(newlocator);

if(p.second==false)
PrjError::prjError(PrjError::ERR_INSERT_NEW);
ii=p.first;
}


///////////////////////////////////////////////////////////////////////////////
Machine.h

#ifndef _MACHINE_H
#define _MACHINE_H

#include <string>

using namespace std;

class Machine
{
protected:
string machinename;
public:
Machine();
Machine(const Machine & mac);
~Machine();
inline void SetMachinename(const string &name){machinename=name;}
inline string GetMachinename(){return machinename;}
};

#endif

Machine.cpp
#include "Machine.h"

Machine::Machine()
{
machinename="";
}
Machine::Machine(const Machine &mac)
{
machinename=mac.machinename;
}

Machine::~Machine()
{
}

///////////////////////////////////////////////////////////////////////
PrjError.h

#ifndef _PRJERROR_H
#define _PRJERROR_H


class PrjError
{
public:
enum ERROR_ENUM
{
ERR_BAD_PRJNAME,
ERR_BAD_SETUPNAME,
ERR_ALREADY_EXIST,
ERR_BAD_CADNAME,
ERR_NOT_FIND,
ERR_INSERT_NEW,

ERR_MAX_NUM
};
PrjError(ERROR_ENUM err);
const char* geterrormsg(ERROR_ENUM err);
const char* geterrormsg();
inline int geterror(){return (int)cur_err;}

protected:
int cur_err;
static const char*msg[ERR_MAX_NUM];
};


#endif

PrjError.cpp
#include "PrjError.h"

const char *PrjError::msg[PrjError::ERR_MAX_NUM]={
"ERROR: Project name can't be empty",
"ERROR:Setup name can't be empty",
"ERROR: Project has already existed",
"ERROR: CAD name can't be empty",

"Error:Can't find",
"Error:Fail to insert new element"
};

PrjError::prjError(ERROR_ENUM err)
{
cur_err=err;
};

const char*PrjError::geterrormsg(ERROR_ENUM err)
{
return this->msg[err];
}
const char* PrjError::geterrormsg()
{
return this->msg[cur_err];
}

///////////////////////////////////////////////////////////////////////////////////
PrjManager.h

#ifndef _PRJMANAGER_H
#define _PRJMANAGER_H

#include <map>
#include <list>
#include <string>

#include "Project.h"
#include "PrjError.h"

using namespace std;

class PrjManager{

public:
PrjManager();
~PrjManager();

void AddPrj(const Project &prj,const string &prjname);
void SavePrj(const Project &prj);
void OpenPrj(const string &prjname);
string GetCurrentprj();
void SetCurrentprj(const string &prjname);

//this is only for test
void GetPrjlist();

protected:
map<string,Project*> prjlists;
Project *currentPrj;
string currentPrjName;
};

#endif

PrjManager.cpp
#include "PrjManager.h"
#include <iostream>

PrjManager::prjManager()
{
currentPrjName="";

}

PrjManager::~PrjManager()
{
map<string,Project*>::iterator ii;

for(ii=prjlists.begin();ii!=prjlists.end();++ii)
prjlists.erase(ii);
}

void PrjManager::AddPrj(const Project &prj,const string &projname)
{

map<string,Project*>::iterator ii;
Project *newPrj=NULL;

char name[256];
strcpy(name,projname.c_str());
if(projname.length()==0)
throw PrjError::prjError(PrjError::ERR_BAD_PRJNAME);

ii=prjlists.find(projname);
if(ii!=prjlists.end())
throw PrjError::prjError(PrjError::ERR_ALREADY_EXIST);

newPrj=new Project(prj);
prjlists[projname]=newPrj;

}

string PrjManager::GetCurrentprj()
{
return currentPrjName;
}

void PrjManager::SetCurrentprj(const string &prjname)
{
map<string,Project*>::iterator ii;

if(prjname.length()==0)
currentPrjName="";
if(prjname!=currentPrjName)
{
ii=prjlists.find(prjname);
if(ii==prjlists.end())
throw PrjError::prjError(PrjError::ERR_NOT_FIND);
currentPrjName=ii->first;
currentPrj=ii->second;
}
}



void PrjManager::GetPrjlist()
{
map<string,Project*>::iterator ii;

for(ii=prjlists.begin();ii!=prjlists.end();ii++)
{
cout << "Project Name: " << ii->first << "\n "<<endl;
}
}

/////////////////////////////////////////////////////////////////////////////
Project.h
#ifndef _PROJECT_H
#define _PROJECT_H

#include <string>
#include "SetupManager.h"
#include "PrjError.h"

using namespace std;

class Project{
public:
Project();
Project(const Project &prj);
~Project();

inline string GetPrjName(){return prjname;}
inline void SetPrjName(const string &name){prjname=name;}



inline string GetCadName(){return cadname;}
inline void SetCadName(const string name){cadname=name;}

inline void SetSetupmanager(SetupManager& mag){setup=mag;}

inline void GetSetupmanager(SetupManager &mag){mag=setup;}


protected:
string prjname;
//cad name
string cadname;

SetupManager setup;

};


#endif

Project.cpp
#include "Project.h"

Project::project()
{
prjname="";
cadname="";

}

Project::project(const Project &prj)
{
prjname=prj.prjname;

cadname=prj.cadname;
setup=prj.setup;

}

Project::~Project()
{
}

//////////////////////////////////////////////////////////
Setup.h
#ifndef _SETUP_H
#define _SETUP_H

#include <string>
#include <list>
#include "Machine.h"
#include "Fixture.h"
//#include "Orientation.h"

using namespace std;

class Setup
{

protected:
string setupname;

Machine machineinfo;
Fixture fixtureinfo;
list<string> willfaces;
list<string> finishedfaces;

public:

Setup();
Setup(const Setup&setup);
// ~Setup();
//for operator =
Setup& operator=(const Setup &it);

inline string GetSetupname(){return setupname;}
inline void SetSetupname(const string &name){setupname=name;}
inline void GetMachine(Machine &mac){mac=machineinfo;}
inline void SetMachine(Machine &machine){machineinfo=machine;}
inline void GetFixture(Fixture &fix){fix=fixtureinfo;}
inline void SetFixture( Fixture &fix){fixtureinfo=fix;}
inline void GetFinishedfaces(list<string> &finish)
{finish=finishedfaces;}
// inline void SetFinishedfaces(list<string> &feature)
{finishedfaces=feature;}
inline void GetWillfaces(list<string> &will){will=willfaces;}
// inline void SetWillfaces(list<string> &will){willfaces=will;}

void AddWillFace(const string &face);
void AddFinishedFace(const string &face);

void DeleteWillFace(const string &face);
void DeleteFinishedFace(const string &face);

void RenameWillFace(const string &oldface,const string &newface);
void RenameFinishedFace(const string &oldface,const string &newface);
};


#endif

Setup.cpp
#include "Setup.h"
#include "PrjError.h"
#include <algorithm>

Setup::Setup()
{
setupname="";
}
Setup::Setup(const Setup &setup)
{
finishedfaces=setup.finishedfaces;
fixtureinfo=setup.fixtureinfo;
machineinfo=setup.machineinfo;
// orient=setup.orient;
willfaces=setup.willfaces;

}

Setup& Setup::eek:perator =(const Setup &it)
{
if(this!=&it)
{
this->finishedfaces=it.finishedfaces;
this->willfaces=it.willfaces;
this->fixtureinfo=it.fixtureinfo;
this->machineinfo=it.machineinfo;
}
return *this;
}


Setup::~Setup()
{
/* willfaces.erase(willfaces.begin(),willfaces.end());
finishedfaces.erase(finishedfaces.begin(),finishedfaces.end());*/
}

void Setup::AddFinishedFace(const string &face)
{
list<string>::iterator ii;

ii=find(finishedfaces.begin(),finishedfaces.end(),face);


if(ii!=finishedfaces.end())
throw PrjError::prjError(PrjError::ERR_ALREADY_EXIST);
finishedfaces.push_back(face);
}

void Setup::AddWillFace(const string &face)
{
list<string>::iterator ii;
ii=find(willfaces.begin(),willfaces.end(),face);

if(ii!=willfaces.end())
throw PrjError::prjError(PrjError::ERR_ALREADY_EXIST);
willfaces.push_back(face);
}

void Setup::DeleteFinishedFace(const string &face)
{
list<string>::iterator ii;
ii=find(finishedfaces.begin(),finishedfaces.end(),face);
if(ii==finishedfaces.end())
throw PrjError::prjError(PrjError::ERR_NOT_FIND);
finishedfaces.erase(ii);
}

void Setup::DeleteWillFace(const string &face)
{
list<string>::iterator ii;
ii=find(willfaces.begin(),willfaces.end(),face);
if(ii==willfaces.end())
throw PrjError::prjError(PrjError::ERR_NOT_FIND);
willfaces.erase(ii);
}

void Setup::RenameFinishedFace(const string &oldface,const string
&newface)
{
list<string>::iterator ii;
ii=find(finishedfaces.begin(),finishedfaces.end(),oldface);
if(ii==finishedfaces.end())
throw PrjError::prjError(PrjError::ERR_NOT_FIND);

*ii=newface;
}

void Setup::RenameWillFace(const string &oldface,const string
&newface)
{
list<string>::iterator ii;
ii=find(willfaces.begin(),willfaces.end(),oldface);
if(ii==willfaces.end())
throw PrjError::prjError(PrjError::ERR_NOT_FIND);
*ii=newface;
}


///////////////////////////////////////////////////////////////////////////////////////////////
SetupManager.h
#ifndef _SETUPMANAGER_H
#define _SETUPMANAGER_H

#include <string>
#include <map>
#include "Setup.h"
using namespace std;
class SetupManager
{
protected:
map<string,Setup*> setuplists;
Setup *currentSetup;
string currentSetupId;

public:
SetupManager();
SetupManager(const SetupManager& mag);
~SetupManager();
void AddSetup(const Setup &setup,const string &setupname);
void DeleteSetup(const string &setupname);
void RenameSetup(const string &oldname,const string &newname);
inline string GetCurrentSetup(){return currentSetupId;}
void SetCurrentSetup(const string &setupname);

//remap
template<class Map, typename Key>
bool remap(Map& map, Key const& oldKey, Key const& newKey)
{

Map::iterator const oldPos = map.find( oldKey );
if( oldPos == map.end() )
return false;
std::pair<Map::iterator,bool> insInfo
= map.insert( Map::value_type(newKey, oldPos->second) );
if( insInfo.second == false ) // new key already exists -> not
added
return (insInfo.first==oldPos); //-> true if both keys
equivalent
// NOTE: if the two keys are equivalent for the map without
actually
// being identical, the value of the key is not changed.
std::swap( oldPos->second, insInfo.first->second ); //move value
map.erase( oldPos );
return true;
}

//this is only used for test
// void GetSetupmanager();


};

#endif

SetupManager.cpp
#include "SetupManager.h"
#include "Machine.h"
#include "Setup.h"
#include "PrjError.h"
#include "Fixture.h"
#include <iostream>

SetupManager::SetupManager()
{
currentSetupId="";
}
SetupManager::SetupManager(const SetupManager &mag)
{
currentSetupId=mag.currentSetupId;
currentSetup=mag.currentSetup;
setuplists=mag.setuplists;
}
SetupManager::~SetupManager()
{

map<string,Setup*>::iterator ii;
for(ii=setuplists.begin();ii!=setuplists.end();++ii)
delete(ii->second);
setuplists.clear();
/* map<string,Setup*>::iterator begin,end;
begin=++setuplists.begin();
end=--setuplists.end();
setuplists.erase(begin,end);*/

}

void SetupManager::AddSetup(const Setup &setup,const string
&setupname)
{
map<string,Setup*>::iterator ii;

Setup *newSetup=NULL;

if(setupname.length()==0)
throw PrjError::prjError(PrjError::ERR_BAD_SETUPNAME);

ii=setuplists.find(setupname);

if(ii==setuplists.end())
{
newSetup=new Setup(setup);
setuplists[setupname]=newSetup;
}
else
throw PrjError::prjError(PrjError::ERR_NOT_FIND);

}




void SetupManager::DeleteSetup(const string& setupname)
{
map<string,Setup*>::iterator ii;
ii=setuplists.find(setupname);
if(ii==setuplists.end())
throw PrjError::prjError(PrjError::ERR_NOT_FIND);
delete(ii->second);
setuplists.erase(ii);
}

void SetupManager::RenameSetup(const string& oldname,const string
&newname)
{
map<string,Setup*>::iterator ii;
if(newname.length()==0)
throw PrjError::prjError(PrjError::ERR_BAD_SETUPNAME);
ii=setuplists.find(oldname);
if(ii==setuplists.end())
throw PrjError::prjError(PrjError::ERR_NOT_FIND);
// (*ii).first=newname;
this->remap<map<string,Setup*>,string> (setuplists,oldname,newname);


}

void SetupManager::SetCurrentSetup(const string &setupname)
{
map<string,Setup*>::iterator ii;
if(setupname.length()==0)
throw PrjError::prjError(PrjError::ERR_BAD_SETUPNAME);
else if(setupname!=currentSetupId)
{
ii=setuplists.find(setupname);
if(ii==setuplists.end())
throw PrjError::prjError(PrjError::ERR_NOT_FIND);
currentSetupId=setupname;
currentSetup=ii->second;
}
}

/////////////////////////////////////////////////////////////////////////////////////

Ugoperation.h
#ifndef _UGOPERATION_H
#define _UGOPERATION_H

#include <string>
using namespace std;

class Ugoperation
{
protected:
string faceId;
string pointId;
string locatorId;
string cadname;

public:

void Ug_opencad(const string &name);
void Ug_getface();
void Ug_getpoint();
void Ug_getlocator();

inline void Ug_setfaceid(const string &id){faceId=id;}
inline string Ug_getfaceid(){return faceId;}
inline void Ug_setpointid(const string &id){pointId=id;}
inline string Ug_getpointid(){return pointId;}
inline void Ug_setlocatorid(const string &id){locatorId=id;}
inline string Ug_getlocatorid(){return locatorId;}
};


#endif

Ugoperation.cpp
#include "Ugoperation.h"
#include<iostream>
#include<sstream>

int testface=10;
int testpoint=100;
int testlocator=1000;
string cadname("c:/test.prt");

void Ugoperation::Ug_getface()
{
//here is only for test,later should add some ug api functions
stringstream s;
testface+=1;
s << testface;

faceId=s.str();
}

void Ugoperation::Ug_getpoint()
{
//here is only for test
stringstream s;
testpoint+=1;
s<<testpoint;

pointId=s.str();
}

void Ugoperation::Ug_getlocator()
{
stringstream s;
testlocator+=1;
s << testlocator;

locatorId=s.str();
}


void Ugoperation::Ug_opencad(const string &name)
{
//only for test

cadname=name;
}

/////////////////////////////////////////////////////////////////////////////////////////
testmain.cpp
#include "PrjManager.h"
#include "Project.h"
#include "PrjError.h"
#include "Setup.h"
#include "Ugoperation.h"
#include "Fixture.h"
#include "Machine.h"
#include "SetupManager.h"

#include <string>
#include <iostream>
using namespace std;

int main()
{
PrjManager prjmanager;
Ugoperation op;
Fixture fix;
Machine mac;
Setup setup;
SetupManager setupmag;

// vector<string> pfaces;

string macname("Machine1");

Project prj;
// Project prj2;

string facename[3];
string pointname[6];
string locator[6];

//suppose get three faces
op.Ug_getface();
facename[0]=op.Ug_getfaceid();
op.Ug_getface();
facename[1]=op.Ug_getfaceid();
op.Ug_getface();
facename[2]=op.Ug_getfaceid();

//get six points
for(int i=0;i<6;i++)
{
op.Ug_getpoint();
pointname=op.Ug_getpointid();
op.Ug_getlocator();
locator=op.Ug_getlocatorid();
}

for(int i=0;i<3;i++)
{
fix.AddLocateFace(facename);

}

// fix.GetFacesFromVector(pfaces);


for(int j=0;j<6;j++)
{
if(j<3)
fix.AddLocatePoint(facename[0],pointname[j]);
if(j>2 && j<5)
fix.AddLocatePoint(facename[1],pointname[j]);
if(j==5)
fix.AddLocatePoint(facename[2],pointname[j]);
}

for(int j=0;j<6;j++)
{
fix.AddLocator(pointname[j],locator[j]);
}

setup.SetFixture(fix);

//add machine info
mac.SetMachinename(macname);

setup.SetMachine(mac);


//add will faces and finished faces, here is only for test
list<string> will;
list<string> finish;

string willface[2]={"001","002"};
string finishedface[4]={"003","004","005","006"};
for(int i=0;i<4;i++)
{
setup.AddFinishedFace(finishedface);
}
for(int i=0;i<2;i++)
setup.AddWillFace(willface);


//to deal with setup manager
setupmag.AddSetup(setup,"setup1");

setupmag.SetCurrentSetup("setup1");

// setupmag.GetSetupmanager();

prj.SetSetupmanager(setupmag);

// prj.SetPrjName("projetct 1");

prjmanager.AddPrj(prj,"project 1");
return 0;

}
 
P

Phlip

David said:
something wrong with my code, it seems that the destructor function
has been called twice. I don't know why.here is my codes

Tip: Keep pulling lines, functions, and classes out of that until it
reproduces the bug in the minimum lines possible.

Only then post the sample code.

But that tip runs the risk of exposing the bug for you...
 
R

red floyd

David said:
Hi all,
something wrong with my code, it seems that the destructor function
has been called twice. I don't know why.here is my codes
Fixture.h
#ifndef _FIXTURE_H
#define _FIXTURE_H
[remainder redacted]

This is most likely not the cause of your problem, but your program is
ill-formed.

Any identifier with a leading underscore followed by an uppercase letter
is reserved to the implementation -- you may not use it for your own
purposes.
 
R

Ron Natalie

David said:
Hi all,
something wrong with my code, it seems that the destructor function
has been called twice. I don't know why.here is my codes
Fixture.h
\
Your code is too large for any sane person to want to diagnose.
Cut it down.

Without bothering to look to carefully, absent any explicit
destructor calls, my guess is that your destructor IS NOT
being called twice, but in fact you're missing the fact that
a temporary object is being constructed somewhere and you're
seeing that object being destructed.

Check all your copy-assignment operatosr and copy constructors
for proper operation. Remember things are put into and moved
around standard containers by copying.

I note specifically that you are violating the "rule of three."
While you have copy constructors and destuctors, your classes
lack a definition of an assignment operator. This is particularly
bad since you use assignment all over the place in your code.
 
R

Ralph D. Ungermann

David said:
Hi all,
something wrong with my code, it seems that the destructor function
has been called twice. I don't know why.here is my codes

Do you mean Fixture::~Fixture() ? Then there is nothing wrong with your
code: you have two such objects.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,152
Members
46,697
Latest member
AugustNabo

Latest Threads

Top