私はサンゴの成長をシミュレートすることを目的としたプログラムを作成しています。サンゴをある種のバイナリツリーにしたいと考えています。ブランチはノードに相当します。私がプログラムを実行すると、 "セグメンテーションフォールト"エラーが発生し、テストしていくつかの研究を行った後、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;
}
ようこそスタックオーバーフロー。 [The Tour](http://stackoverflow.com/tour)を読み、[ヘルプセンター](http://stackoverflow.com/help/asking)の資料を参考にしてください。ここに聞いてください。 –
このような問題を解決する適切なツールは、デバッガです。スタックオーバーフローを尋ねる前に、コードを一行ずつ進める必要があります。詳しいヘルプは、[小さなプログラムをデバッグする方法(Eric Lippert)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)を参照してください。最低限、問題を再現する[最小、完全、および検証可能](http://stackoverflow.com/help/mcve)の例と、その問題を再現するためのデバッガ。 –
_ "CoralクラスのデストラクタがNULLオブジェクトを削除しようとしているためです。" 'NULL'または' nullptr'で 'delete'を使うと完全に問題ありません。 'delete'を呼び出すと、ポインタの値は' NULL'または 'nullptr.'に設定されません。 –