Problem with copy constructor.
I'm having some trouble with my copy constructor. I've tried using gdb
to find the bug, but it seg faults in the destructor. I'm not able to
see what I'm doing wrong. Since I'm using pointers, I need deep copy
and I believe I'm doing that in my constructors. Can someone help me
see what I'm missing out? Here is my code.
typedef boost::shared_ptr<Factor> FactorPtr;
enum FactorTypeT
{ FACTOR_ZERO, FACTOR_ONE, FACTOR_AND, FACTOR_OR};
class Factor
{
private:
struct FactorImpl *fact;
Factor();
Factor(const FactorTypeT type, const int index,
const Factor *next, const Factor *same);
Factor(const Factor& rhs);
static FactorPtr convNodeToFactor(const NodePtr& n, const NodePtr&
ntree);
static FactorPtr convNodeToFactorRecur(const NodePtr& n, const
NodePtr& ntree);
public:
~Factor();
static FactorPtr create();
static FactorPtr create(const FactorPtr& rhs);
};
struct FactorImpl
{
FactorTypeT type;
int idx;
struct FactorImpl *nextlevel;
struct FactorImpl *samelevel;
FactorImpl()
: type(FACTOR_UNKNOWN), idx(-1), nextlevel(0), samelevel(0) {}
// copy constructor
FactorImpl(const FactorImpl& rhs)
{
*this = rhs;
}
~FactorImpl()
{
if (nextlevel)
delete nextlevel;
if (samelevel)
delete samelevel; <------------ it segfaults here
}
FactorImpl& operator=(const FactorImpl& rhs)
{
if (this != &rhs)
{
type = rhs.type;
idx = rhs.idx;
if (rhs.nextlevel)
nextlevel = new FactorImpl(*rhs.nextlevel); <--- deep copy
right?
if (rhs.samelevel)
samelevel = new FactorImpl(*rhs.samelevel); <-- deep copy
right?
}
return *this;
}
void dump(std::ostream& f)
{
static std::string str[7] = {"-0-", "-1-", "AND", "OR", "???"};
f << this << " " << str[type] << " " << idx << "\n";
if (nextlevel)
nextlevel->dump(f);
if (samelevel)
samelevel->dump(f);
}
};
Factor::Factor()
: fact(new FactorImpl()) {}
Factor::Factor(const FactorTypeT type, const int index,
const Factor *next, const Factor *same)
: fact(new FactorImpl())
{
fact->type = type;
fact->idx = index;
if (next)
fact->nextlevel = new FactorImpl(*next->fact); <----
making deep copy?
if (same)
fact->samelevel = new FactorImpl(*same->fact); <---- making
deep copy ?
}
Factor::~Factor()
{
delete fact;
}
Factor::Factor(const Factor& rhs)
: fact(new FactorImpl())
{
*fact = *(rhs.fact);
}
FactorPtr Factor::create()
{
FactorPtr f(new Factor());
return f;
}
FactorPtr Factor::create(const FactorPtr& rhs)
{
FactorPtr f(new Factor(*rhs));
return f;
}
FactorPtr Factor::convNodeToFactor(const NodePtr& n, const NodePtr&
ntree)
{
switch (ntree->getFunction())
{
case NODE_ZERO:
return FactorPtr(new Factor(FACTOR_ZERO, -1, 0, 0));
case NODE_ONE:
return FactorPtr(new Factor(FACTOR_ONE, -1, 0, 0));
default:
return Factor::convNodeToFactorRecur(n, ntree);
}
}
FactorPtr Factor::convNodeToFactorRecur(const NodePtr& n, const
NodePtr& ntree)
{
if (ntree->getType() != NODE_UNASSIGNED)
return FactorPtr(new Factor(FACTOR_LEAF, n->faninIndex(ntree), 0,
0));
unsigned int j;
NodePtr fanin;
FactorPtr lit, tmp, gand, gor, curand, curor;
gor = curor = FactorPtr();
for (int i = ntree->numCubes() - 1; i >= 0; --i)
{
gand = curand = FactorPtr();
foreach_fanin(ntree, j, fanin)
{
switch (ntree->getLiteral(i, j))
{
case VZERO:
tmp = Factor::convNodeToFactorRecur(n, fanin);
lit = FactorPtr(new Factor(FACTOR_INV, -1, 0, tmp.get()));
<------- this line causes a segfault. the problem is with pass
tmp.get() (which is a valid pointer to object) so I need to do a deep
copy. not sure if i'm doing deep copy correctly.
break;
case VONE:
lit = Factor::convNodeToFactorRecur(n, fanin);
break;
default:
break;
}
if (!curand)
gand = curand = lit;
else
{
curand->fact->samelevel = (lit.get())->fact;
curand = lit;
}
}
if (!gand)
bailOut("Factor::convNodeToFactorRecur()",
ERROR_NODE_NOT_MINIMALBASE_FUNCTION);
else if (!gand->fact->samelevel)
gand = FactorPtr(new Factor(FACTOR_AND, -1, 0, gand.get()));
if (!gor)
gor = curor = gand;
else
{
curor->fact->samelevel = (gand.get())->fact;
curor = gand;
}
}
if (!gor)
bailOut("Factor::convNodeToFactorRecur()",
ERROR_NODE_NOT_MINIMALBASE_FUNCTION);
else if (!gor->fact->samelevel)
gor = FactorPtr(new Factor(FACTOR_OR, -1, 0, gor.get()));
return gor;
}
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0xbf7ffffc
0x000b3b20 in FactorImpl::~FactorImpl (this=0xd010c0) at factor.cpp:52
52 delete samelevel;
thanks for any help.