2017-02-19 119 views
0

的複製成員我有一個結構

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

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

給出一個結構NodeBox我有兩個功能insert()sonumb(),我想用這些結構。

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()返回一個整數值bsonboxsonumb()小盒子裏面t->box通話後表示。通話結束後,我會返回sonbox的正確值。所以sonbox不是空的。但是,如果我想複製像t->son[b]->box = sonbox那樣的值,則會出現分段錯誤。我錯過了什麼?

+4

'sonbox'不是空的兩種方式。對於段錯誤的可能原因是'b < 0 || b > 3'或'T->子並[b]'被初始化。 – StoryTeller

+1

對不起,但請回到[幫助]並再次閱讀如何問「代碼無法正常工作」的問題。它從提供[mcve]開始。你有一個代碼錯誤;但你只是顯示你的代碼的一部分。 – GhostCat

+1

'son'是結構體指針數組,你需要在''malloc''前分配內存,然後給每個元素賦予框 –

回答

1

你幾乎肯定少不了son要素的分配。爲了使表達t->son[b]->box以產生分配的一個有效的目標,t->son[b]需要分配一個指針指向一個有效Node結構。指針需要指向您之前分配的某個Node

如果子節點的節點之間共享,這應該是一個malloc -ed節點。這增加了相當多的複雜性,因爲刪除共享節點不是微不足道的。處理共享節點的兩種常見方法是(1)在大數組中一次分配所有節點,並在需要時逐個使用它們;(2)將引用計數添加到struct,並在取一個指針,並在不再需要引用時遞減它。第二種方法非常難以實施;看看你是否可以在承諾之前避免它。

在另一方面,如果子節點是由其父獨家擁有的,你有一個非常簡單的解決方案:son[b]元件的指派之前malloc分配Node,並且free他們當你與節點完成:

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

使用calloc可確保Node的內存在進行其他分配前被清除。如果這是沒有必要的,因爲您將所有成員你的函數的其餘部分,與malloc更換電話:

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

爲什麼沒有星號?我從一本書中得到了代碼,我嘗試瞭解代碼。有一個星號被使用。子節點僅由其父節點擁有。 – Samuel

+0

@Samuel我明白了爲什麼將'Node'放置在'struct'中的技巧是行不通的。查看編輯。 – dasblinkenlight

+0

我更新了我的問題並添加了函數'sonumb()'。你的答案是否仍然適用於它? – Samuel

0

增加@ dasblinkenlight的評論。

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.