2017-02-16 7 views
0

私はサンゴの成長をシミュレートすることを目的としたプログラムを作成しています。サンゴをある種のバイナリツリーにしたいと考えています。ブランチはノードに相当します。私がプログラムを実行すると、 "セグメンテーションフォールト"エラーが発生し、テストしていくつかの研究を行った後、CoralクラスのデストラクタがNULLオブジェクトを削除しようとしているためだと思っています。しかし、私はデストラクタの仕組みを完全には理解していないので、クラスのコンセプトには全く慣れていないので、解決する方法は分かりません。このデストラクタでは何が起こっていますか? (segfault)

CoralBranchとCoralクラスが宣言されているヘッダーファイル、クラスが実装されている.cpp、main.cppを提供します。

ありがとうございます。

私の問題を再現する最小、完全、および検証可能な例で作業しても、問題は発生しません。私は問題にならないはずのメソッドでセグメンテーションフォールトを引き起こす私のプログラムには他のエラーがあると思います。

coral2.h

#ifndef __CORAL2_H_INCLUDED__ 
#define __CORAL2_H_INCLUDED__ 

class CoralBranch{ 

    public: 

CoralBranch(); // class constructor 1 
CoralBranch(double xpos, double zpos, double th); // class constructor 2 
~CoralBranch(); 

CoralBranch *left; // pointer to left child 
CoralBranch *right; // pointer to right child 
double x; // x-position of the beggining of the branch 
double z; // z-position of the beggining of the branch 
double theta; // branch's direction: angle between the branch and z-axis 
double length; // branch's length 
int state; // state==1: branch is able to grow, state==0: branch can't grow 

}; 


class Coral{ 

    public: 

Coral(); // class constructor 1 
Coral(double bl, double gr, double ir, double dt); // class constructor 2 
~Coral(); // class destructor 

// adds theta-oriented left son to coral-branch *leaf 
void add_left(CoralBranch *leaf, double theta); 
// adds theta-oriented right son to coral-branch *leaf 
void add_right(CoralBranch *leaf, double theta); 
// destroys coral-branch *branch and its decendents 
void destroy_coral(CoralBranch *branch); 
// tests if the growing branch influence zone penetrates testbranch influence zone 
void distance_test(Coral crl, CoralBranch *growingbranch, CoralBranch *testbranch); 
// tests if the growing branch is big enough to have children and adds them 
void branching_test(Coral crl, CoralBranch *growingbranch, double thetaleft, double thetaright); 
// applies grow mechanism to growing branch 
void branch_grow(Coral crl, CoralBranch *growingbranch); 
// simulates the growing process for the entire colony after one time step by 
// applying "branch_grow" to the whole colony 
void coral_grow(Coral crl, CoralBranch *growingbranch); 

    //private: 

CoralBranch *trunk; 

double branching_length; 
double growth_rate; 
double influence_radius; 
double Deltat; 


}; 

#endif 

coral2.cpp(のみコンストラクタとデストラクタ)

CoralBranch::CoralBranch():left(NULL),right(NULL),x(0.0),z(0.0),theta(0.0),length(1.0),state(1) 
{ 
// there isn't any methods in this class 
} 

CoralBranch::CoralBranch(double xpos, double zpos, double th):left(NULL),right(NULL),x(xpos),z(zpos),theta(th),length(1.0),state(1) 
    { 

    } 

CoralBranch::~CoralBranch(){ 

    delete left; 
    delete right; 

} 

Coral::Coral(){ 

    trunk=new CoralBranch(); 

    branching_length=1.0; 
    growth_rate=1.0; 
    influence_radius=1.0; 
    Deltat=1.0; 

} 

Coral::Coral(double bl, double gr, double ir, double dt){ 

trunk=new CoralBranch(); 
    //trunk=NULL; 

    branching_length=bl; 
    growth_rate=gr; 
    influence_radius=ir; 
    Deltat=dt; 

} 

Coral::~Coral(){ // coral destruction 

    destroy_coral(trunk); 

} 

void Coral::destroy_coral(CoralBranch *branch){ // destroys branch *branch and its decendents 

    if(branch == NULL) return; 

    destroy_coral(branch->left); 
    destroy_coral(branch->right); 
    delete branch; 

    /*if(branch!=NULL){ 

    destroy_coral(branch->left); // destruction advance 
    destroy_coral(branch->right); 
    delete branch; // currently considered branch is deleted if it exists 

    }*/ 
} 

main.cppに

#include <iostream> 
#include <stdio.h> 
#include <stdlib.h> 
#include "coral2.h" 
#include <math.h> 
using namespace std; 

int main(){ 

    /* Variable declaration, these variables need to be initialized in order to 
    construct the coral with the characteristics we desire */ 
    double branchinglength, growthrate, influenceradius, deltat; 
    /* Declaration and initialization of the total simulation time */ 
    double TotalTime=2; 
    /* Declaration and initialization of counters */ 
    int i=0; 
    int j=0; 
    printf("%d\n",j); 

    /* Initialization of Coral class parameters*/ 
    branchinglength=0.2; 
    growthrate=1.0; 
    influenceradius=0.1; 
    deltat=1.0; 

    /* Creation of the coral object*/ 
    static Coral GrowingCoral(branchinglength, growthrate, influenceradius, deltat); 

    /* Starting growth process */ 
    for(i=0; i<TotalTime; i=i+deltat){ 

    j++; 
    printf("%d\n",j); 

    GrowingCoral.coral_grow(GrowingCoral, GrowingCoral.trunk); 

    } 

    printf("%f\n",GrowingCoral.branching_length); 

    return 0; 
} 
+2

ようこそスタックオーバーフロー。 [The Tour](http://stackoverflow.com/tour)を読み、[ヘルプセンター](http://stackoverflow.com/help/asking)の資料を参考にしてください。ここに聞いてください。 –

+3

このような問題を解決する適切なツールは、デバッガです。スタックオーバーフローを尋ねる前に、コードを一行ずつ進める必要があります。詳しいヘルプは、[小さなプログラムをデバッグする方法(Eric Lippert)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)を参照してください。最低限、問題を再現する[最小、完全、および検証可能](http://stackoverflow.com/help/mcve)の例と、その問題を再現するためのデバッガ。 –

+4

_ "CoralクラスのデストラクタがNULLオブジェクトを削除しようとしているためです。" 'NULL'または' nullptr'で 'delete'を使うと完全に問題ありません。 'delete'を呼び出すと、ポインタの値は' NULL'または 'nullptr.'に設定されません。 –

答えて

1

leftブランチとrightブランチを2回削除しています。 leftブランチとright枝を所有していること:

はどのようにあなたのCoralBranchうまくいくと思います。それはの支店を所有しているので、デストラクタ~CoralBranchにあるdeleteである必要があります。そしてそれはそうです!良い。

あなたのクラスCoralだけオブジェクト、trunkを所有しています。しかし、Coral::destroy_coralは何を見なさい!クラスCoralでないブランチオブジェクトを削除することができます。!それが破壊するはずのCoralBranchだけがtrunkです。その1つは、デストラクタを介して自身の子ブランチを削除し、再帰的に子ブランチを削除します。したがって、再帰的なdestroy_coral呼び出しをdestroy_coralから削除するだけです。

+0

説明をありがとう。私はあなたの言うことをやったが、私は 'Coral :: destroy_coral'にはもう問題はない。しかし、私は今、 'CoralBranch ::〜CoralBranch()'デストラクタでエラーに遭遇します。最初の投稿を編集するための最小限の例で作業していて、プログラムの実行には問題はありませんでした。私のコードには他の問題があると思います... – bengo

関連する問題