免费工作,删除Linux上的段错误。 Windows确定

时间:2016-10-02 04:37:14

标签: c++

我有一些在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;
    }
}

删除似乎会导致问题。免费是好的。有人可能会告诉我不要自由搭配新款,但是我的元素只是尝试不同的东西。

1 个答案:

答案 0 :(得分:2)

第一个节点的析构函数关闭调试文件。

下一个节点的析构函数再次关闭它。这是非法的,可能会崩溃。

当我们在它时,抛弃freeNode函数并将破坏移动到它所属的析构函数。析构函数应如下所示:

 Node::~Node()
 {
     delete nwNode;
     delete swNode;
     delete neNode;
     delete seNode;
 }

就是这样。无需检查空指针或bIsLeaf

更好的是,使用std::unique_ptr,完全抛弃析构函数(规则为零。谷歌吧)。

相关问题