2017-02-16 5 views
0

Ich schreibe ein Programm mit dem Ziel Korallenwachstum zu simulieren und ich möchte, dass Korallen eine Art binärer Baum sind. Zweige sind das Äquivalent von Knoten. Als ich das Programm ausführte, bekam ich einen "segmentation fault" -Fehler und nach dem Testen und Recherchen vermute ich, dass der Destruktor der Coral-Klasse versucht, ein NULL-Objekt zu löschen. Ich habe jedoch keine Ahnung, wie ich es lösen kann, da ich nicht ganz verstehe, wie ein Destruktor funktioniert, und ich bin überhaupt nicht mit dem Konzept der Klasse vertraut.Was passiert mit diesem Destruktor? (segfault)

Ich gebe Ihnen die Header-Datei, wo CoralBranch und Coral-Klassen deklariert sind, die .cpp, wo die Klassen implementiert sind und die main.cpp.

Vielen Dank im Voraus.

Wenn ich in einem minimalen, vollständigen und überprüfbaren Beispiel arbeite, das mein Problem reproduziert, habe ich kein Problem. Ich denke, ich habe andere Fehler in meinem Programm, die die Segmentierungsfehler bei Methoden provozieren, die keine Probleme haben sollten.

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 (nur Konstruktoren und Destruktoren)

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

Willkommen bei Stack Overflow. Bitte nehmen Sie sich die Zeit, [The Tour] (http://stackoverflow.com/tour) zu lesen und beziehen Sie sich auf das Material aus der [Hilfe] (http://stackoverflow.com/help/asking), was und wie Sie können fragen Sie hier. –

+3

Das richtige Werkzeug, um solche Probleme zu lösen, ist Ihr Debugger. Sie sollten Schritt für Schritt durch Ihren Code * gehen, bevor Sie auf Stack Overflow nachfragen. Für weitere Hilfe lesen Sie bitte [Wie kleine Programme zu debuggen (von Eric Lippert)] (https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). Zumindest sollten Sie Ihre Frage bearbeiten, um ein [minimales, vollständiges und verifizierbares] (http://stackoverflow.com/help/mcve) Beispiel einzufügen, das Ihr Problem zusammen mit den Beobachtungen, die Sie in der Debugger. –

+4

_ "weil der Destruktor der Coral-Klasse versucht, ein NULL-Objekt zu löschen." _ Mit 'delete' mit' NULL' oder 'nullptr' ist völlig in Ordnung. Obwohl "delete" aufgerufen wird, wird der Zeigerwert nicht auf "NULL" oder "nullptr" gesetzt. –

Antwort

1

Sie löschen die Zweige left und right zweimal.

Denken Sie, wie Sie Ihre CoralBranch Werke: Es besitzt einen left Zweig und einen right Zweig. Da es besitzt die Zweige, kann und sollte delete sie in der Destruktor ~CoralBranch. Und es tut! Gut.

Ihre Klasse Coralbesitzt nur ein Objekt, das trunk. Aber schau was Coral::destroy_coral tut! Es ist erlaubt, Zweigobjekte zu löschen, die Coralnicht besitzen! Die einzige CoralBranch, die es zerstören sollte, ist die, die es besitzt, trunk. Dieser wird seine eigenen untergeordneten Zweige über den Destruktor und die eigenen rekursiv löschen. Daher müssen Sie nur die rekursiven Aufrufe destroy_coral von destroy_coral entfernen.

+0

Danke für die Erklärung. Ich habe getan was du sagst und ich habe keine Probleme mehr mit "Coral :: destroy_coral". Allerdings habe ich jetzt einen Fehler im Desaster 'CoralBranch :: ~ CoralBranch()'. Ich habe in einem minimalen Beispiel gearbeitet, um meinen ersten Post zu bearbeiten, aber ich hatte kein Problem mit dem Programm. Ich denke, mein Code hat andere Probleme ... – bengo

Verwandte Themen