2017-02-19 3 views
0

Ich habe eine Struktur Node und Box gegeben durchKopieren Mitglieder einer Struktur

typedef struct Node{ 
    Particle p; 
    Box box; 
    struct Node *son[4]; 
}Node 

und

typedef struct Box{ 
    double low[3]; 
    double up[3]; 
}Box 

Ich habe zwei Funktionen insert() und sonumb(), wo ich diese Strukturen verwenden möchten.

void insert(Particle *p, Node *t){ 
     Box sonbox; 
     int b=sonumb(&t->box, &sonbox, p); 
     t->son[b]->box = sonbox; // <--- Produces Segmentation fault (core dumped) 
    } 

int sonumb(Box *box, Box *sonbox, Particle *p){ 
     int b=0; 
     for(int d=0;d<3;d++){ 
      sonbox->up[d] = 0.5*box->up[d]; 
      sonbox->low[d] = 0.5*box->low[d]; 
      } 
      b=1; // b=[0,3] just for this example 
    } 

sonum() gibt einen ganzzahligen Wert b. sonbox stellt nach dem Anruf sonumb() eine kleinere Box innerhalb von t->box dar. Ich gebe die richtigen Werte für sonbox nach dem Anruf zurück. Also sonbox ist nicht leer. Aber wenn ich diese Werte wie t->son[b]->box = sonbox kopieren möchte, bekomme ich einen Segmentationsfehler. Was habe ich verpasst?

+4

'sonbox' ist nicht so oder so leer. Mögliche Ursachen für einen segfault sind 'b < 0 || b > 3' oder' t-> son [b] 'sind nicht initialisiert. – StoryTeller

+1

Entschuldigung, aber wenden Sie sich bitte wieder an die [Hilfe] und lesen Sie noch einmal, wie Sie "code not working" -Fragen stellen können. Es beginnt mit der Bereitstellung eines [mcve]. Sie haben einen Code-Fehler; aber Sie zeigen nur Teile Ihres Codes. – GhostCat

+1

Der 'Sohn' ist struct Zeigerarray und Sie müssen Speicher mit' malloc' reservieren, bevor Sie jedem Element –

Antwort

1

Sie haben fast sicher die Zuweisung von son Elemente verpasst. Damit der Ausdruck t->son[b]->box ein gültiges Ziel einer Zuweisung erzeugt, muss t->son[b] ein Zeiger auf eine gültige Struktur Node zugewiesen werden. Der Zeiger muss auf Node zeigen, die Sie zuvor zugewiesen haben.

Wenn untergeordnete Knoten unter Knoten gemeinsam genutzt werden, sollte dies ein malloc-Knoten sein. Dies fügt ein gewisses Maß an Komplexität hinzu, da das Löschen gemeinsamer Knoten nicht-trivial ist. Zwei gängige Vorgehensweisen zum Arbeiten mit gemeinsam genutzten Knoten sind (1) alle Knoten auf einmal in einem großen Array zuzuteilen und sie nacheinander zu verwenden, wenn sie benötigt werden, und (2) den Referenzzähler zu struct hinzuzufügen, ihn zu erhöhen Nehmen Sie einen Zeiger und dekrementieren Sie ihn, wenn die Referenz nicht mehr benötigt wird. Der zweite Ansatz ist extrem schwierig zu implementieren; sehen Sie, ob Sie es vermeiden können, bevor Sie sich dazu verpflichten.

Auf der anderen Seite, wenn Kind-Knoten ausschließlich von ihren Eltern im Besitz ist, haben Sie eine sehr einfache Lösung: Node mit malloc vor der Zuweisung von son[b] Elementen zuweisen, und free sie, wenn Sie mit dem Knoten fertig sind:

Box sonbox; 
int b=sonumb(&t->box, &sonbox, p); 
t->son[b] = calloc(1, sizeof(Node)); // Allocate the node 
t->son[b]->box = sonbox; 

Die Verwendung von calloc stellt sicher, dass der Speicher des Node gelöscht wird, bevor andere Zuweisungen vorgenommen werden. Wenn dies nicht notwendig ist, weil Sie alle Mitglieder in dem Rest Ihrer Funktion zuweisen, ersetzen Sie den Anruf mit malloc:

t->son[b] = malloc(sizeof(Node)); 
+0

Warum kein Sternchen? Ich habe den Code von einem Buch, wo ich versuche, den Code zu verstehen. Dort wird ein Sternchen verwendet. Untergeordnete Knoten gehören ausschließlich ihren Eltern. – Samuel

+0

@ Samuel Ich sehe, warum der Trick mit der 'Node' in der' struct' nicht funktionieren würde. Siehe die Änderung. – dasblinkenlight

+0

Ich habe meine Frage aktualisiert und die Funktion 'solumb()' hinzugefügt. Gilt Ihre Antwort noch? – Samuel

0

Hinzufügen zu @ dasblinkenlight Kommentar.

Box sonbox; ---> This variable is on stack 
int b=sonumb(&t->box, &sonbox, p); --> content of t->box is COPIED to sonbox, not by reference but by value. 
t->son[b]->box = sonbox; // --> Assigning stack variable is incorrect, because it will vanish once you exit function. OR as @dasblinkenlight suggested pass the value but not the pointer. 
Verwandte Themen