0

I have a struct Node and Box given by

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

and

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

I have two functions insert() and sonumb() where I want to use these structures.

 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() returns an integer value b. sonbox represents after the call of sonumb() a smaller box inside of t->box. I return the right values for sonbox after the call. So sonbox is not empty. But if I want to copy those values like t->son[b]->box = sonbox I get an segmentatioin fault. What did I miss?

7
  • 4
    sonbox is not empty either way. Possible causes for a segfault are b < 0 || b > 3 or t->son[b] being uninitialized. Commented Feb 19, 2017 at 12:25
  • 1
    Sorry, but please turn back to the help center and read again how to ask "code not working" questions. It starts with providing a minimal reproducible example. You have a code bug; but you are only showing parts of your code. Commented Feb 19, 2017 at 12:25
  • 1
    The son is struct pointer array and you need to allocate memory with malloc before you assign box each elements Commented Feb 19, 2017 at 12:27
  • son[b] mostly likely contains/evaluates to garbage. But we do not know, as you do not show the relevant code. Commented Feb 19, 2017 at 12:30
  • @StoryTeller You are right. Now I see my error. Thank you! I forgot to initialize t->son[b]. Commented Feb 19, 2017 at 12:31

2 Answers 2

1

You have nearly certainly missed the allocation of son elements. In order for the expression t->son[b]->box to produce a valid target of an assignment, t->son[b] needs to be assigned a pointer to a valid Node structure. The pointer needs to point to some Node that you have previously allocated.

If child nodes are shared among nodes, this should be a malloc-ed node. This adds quite a bit of complexity, because deleting shared nodes is non-trivial. Two common approaches to working with shared nodes are to (1) allocate all nodes at once in a large array, and use them one-by-one as they become needed, and (2) add reference count to the struct, increment it when taking a pointer, and decrement it when the reference is no longer needed. The second approach is extremely difficult to implement; see if you can avoid it before committing to it.

On the other hand, if child nodes are owned exclusively by their parent, you have a very simple solution: allocate Node with malloc before the assignment of son[b] elements, and free them when you are done with the node:

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

Use of calloc ensures that the memory of the Node is cleared prior to making other assignments. If this is not necessary, because you assign all members in the rest of your function, replace the call with malloc:

t->son[b] = malloc(sizeof(Node)); 
Sign up to request clarification or add additional context in comments.

3 Comments

Why no asterisk? I got the code from a book where I try to understand the code. There an asterisk is used. Child nodes are owned exclusively by their parent.
@Samuel I see why the trick with placing the Node in the struct wouldn't work. See the edit.
I updated my question and added the functionsonumb(). Does your answer still apply to it?
0

adding to @dasblinkenlight's comment.

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. 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.