我有一些在Windows上正常运行的代码。它在Linux上有段错误。当我用免费替换违规删除时,似乎没问题。我对linux比较新,你建议怎么调试呢?我现在真的很想念VS ... 这是有问题的代码,
#include "qtree.hh"
int main(int argc, char* argv[])
{
point a(-3, 3);
point b(3, -3);
Node* pRoot = new Node(a, b);
pRoot->addChild(se);
Node::freeTree(pRoot);
return 0;
}
freeTree()是segfaults的方法。
qtree.hh
#ifndef _QTREE_HH_
#define _QTREE_HH_
#include <cmath>
#include "Body.hh"
#include "stdio.h"
#include "stdlib.h"
enum quadrant {ne, se, sw, nw};
struct point
{
double x;
double y;
point() {}
point(double xarg, double yarg)
{
x = xarg;
y = yarg;
}
};
class Node{
public:
Node(point nw, point se);
~Node();
void addBody(const Body& body);
void addChild(quadrant q);
static void freeTree(Node* pNode);
private:
point nwPoint;
point sePoint;
point comPoint;
double mass;
double dim;
Body* pBody;
Node* nwNode;
Node* neNode;
Node* swNode;
Node* seNode;
bool bIsLeaf;
};
#endif
qtree.cc
#include "qtree.hh"
FILE* fpTree;
const bool dbg = true;
Node::Node(point nw, point se)
{
nwPoint = nw;
sePoint = se;
mass = 0;
pBody = 0;
dim = std::abs(sePoint.x - nwPoint.x);
nwNode = 0;
neNode = 0;
swNode = 0;
seNode = 0;
bIsLeaf = true;
if (dbg && !fpTree)
{
fpTree = fopen("qtree.txt", "w");
}
}
Node::~Node()
{
//close file
if (fpTree) {fclose(fpTree);}
}
void Node::addChild(quadrant q)
{
point nwP = this->nwPoint;
point seP = this->sePoint;
this->bIsLeaf = false;
switch (q)
{
case ne:
{
nwP.x = (this->sePoint.x + this->nwPoint.x)/2;
seP.y = (this->sePoint.y + this->nwPoint.y)/2;
neNode = new Node(nwP, seP);
break;
}
case se:
{
nwP.x = (this->sePoint.x + this->nwPoint.x)/2;
nwP.y = (this->nwPoint.y + this->sePoint.y)/2;
seNode = new Node(nwP, seP);
break;
}
case sw:
{
seP.x = (this->nwPoint.x + this->sePoint.x) / 2;
nwP.y = (this->nwPoint.y + this->sePoint.y)/2;
seNode = new Node(nwP, seP);
break;
}
case nw:
{
seP.x = (this->nwPoint.x + this->sePoint.x) / 2;
seP.y = (this->sePoint.y + this->nwPoint.y) / 2;
nwNode = new Node(nwP, seP);
break;
}
}
if (fpTree)
{
fprintf(fpTree, "adding child of width %f to %s corner of parent",
(this->dim)/2,
(q == nw) ? "nw" :
(q == ne) ? "ne" :
(q == se) ? "se" :
(q == sw) ? "sw" : "invalid");
}
}
void Node::addBody(const Body& body)
{
}
//will free whole tree if arg is root
//recursively free all children then free self
void Node::freeTree(Node* pNode)
{
if (pNode)
{
if (pNode->neNode)
{
if (pNode->neNode->bIsLeaf) {delete(pNode->neNode);}
else {freeTree(pNode->neNode);}
}
if (pNode->seNode)
{
if (pNode->seNode->bIsLeaf) {delete(pNode->seNode);}
else {freeTree(pNode->seNode);}
}
if (pNode->swNode)
{
if (pNode->swNode->bIsLeaf) {delete(pNode->swNode);}
else {freeTree(pNode->swNode);}
}
if (pNode->nwNode)
{
if (pNode->nwNode->bIsLeaf) {delete(pNode->nwNode);}
else {freeTree(pNode->nwNode);}
}
delete pNode;
}
}
删除似乎会导致问题。免费是好的。有人可能会告诉我不要自由搭配新款,但是我的元素只是尝试不同的东西。
答案 0 :(得分:2)
第一个节点的析构函数关闭调试文件。
下一个节点的析构函数再次关闭它。这是非法的,可能会崩溃。
当我们在它时,抛弃freeNode函数并将破坏移动到它所属的析构函数。析构函数应如下所示:
Node::~Node()
{
delete nwNode;
delete swNode;
delete neNode;
delete seNode;
}
就是这样。无需检查空指针或bIsLeaf
。
更好的是,使用std::unique_ptr
,完全抛弃析构函数(规则为零。谷歌吧)。