2017-02-19 98 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.