2016-10-02 38 views
-4

我有一些在Windows上可以正常工作的代碼。它在linux上進行段錯誤。當我用免費替換違規刪除時,它似乎沒問題。我相對較新的Linux,你會推薦什麼來調試呢?我真的錯過VS現在... 這裏是有問題的代碼,免費作品,刪除linux上的segfaults。 Windows ok

#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()是方法段錯誤。

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

'有人可能會說'事實上,因爲它是錯的。 – deviantfan

+1

什麼是'se'?你有這個'se'變量從哪裏冒出來。 – user2357112

+0

而addChild和構造函數的內容也會很有趣... – deviantfan

回答

2

第一個節點的析構函數關閉調試文件。

下一個節點的析構函數再次關閉它。這是非法的,可能會崩潰。

當我們在它的時候,拋棄freeNode函數並將其銷燬到它所屬的析構函數。破壞者應該看起來像這樣:

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

就是這樣。不需要檢查空指針或bIsLeaf

更好的是,使用std::unique_ptr,並完全消除析構函數(規則爲零。谷歌它)。