[英]Why is this segfaulting whilst building a binary tree?
I have found this line in this code through gdb to be seg faulting. 我发现通过gdb在此代码中的这一行是seg错误。 However I can't seem to see why?
但是我似乎看不出为什么? It will run through 6/7 times before a seg fault occurs.
在发生段故障之前,它将运行6/7次。 Temp is a node in a linked list which contains a frequency (int), which I use to find the place in an ascending linked list to insert a new node.
Temp是链表中的一个节点,其中包含一个频率(int),我用它在升序链表中查找插入新节点的位置。
while (ind == 0 && temp != NULL)
{
temp = temp -> next;
if (temp -> frequency > parent_node -> frequency) /*<--- SEG FAULT HERE */
{
parent_node -> next = temp -> next; /* parent points at higher freq node */
temp -> next = parent_node; /* parent node is temp next */
ind = 1;
}
if (temp -> next == NULL)
{
temp -> next = parent_node;
ind = 1;
}
}
You do temp = temp->next
but temp->next
might be nullptr
. 您执行
temp = temp->next
但是temp->next
可能为nullptr
。 You must check its not null before trying to access it's memebers. 您必须先检查它的非null才能尝试访问它的成员。
Here is some code which will insert a new node pointed to by newnode
into a linked list where liststart
points to the first node in the list or is NULL
for an empty list: 这是一些代码,它将由
newnode
指向的新节点插入到链表中,其中liststart
指向列表中的第一个节点,或者对于空列表为NULL
:
if (liststart == NULL) {
liststart = newnode;
newnode->next = NULL;
} else {
struct mylist *prev = liststart;
while (prev->next != NULL && prev->next->frequency <= newnode->frequency) {
prev = prev->next;
}
if (prev->next == NULL) {
prev->next == newnode;
newnode->next = NULL;
} else {
newnode->next = prev->next->next;
prev->next = newnode;
}
}
Here's an alternate version that uses pointers to pointers: 这是使用指针的替代版本:
struct mylist **pprev;
pprev = &liststart;
while (*pprev != NULL && (*pprev)->frequency <= newnode->frequency) {
pprev = &(*pprev)->next;
}
newnode->next = *pprev;
*pprev = newnode;
Your issue is that you check that temp
isn't null, then immediately update temp
, so it may be null again. 您的问题是您检查
temp
不为null,然后立即更新temp
,因此它可能又为null。
(I don't like the name temp
so I've changed it to node
in my examples) (我不喜欢
temp
这个名字,因此在示例中将其更改为node
)
It's clearest if you decompose it, so: 如果分解,这是最清楚的,因此:
while(ind == 0 && node != null) {
node = node -> next; // now node might be null
doStuffWith(node);
}
Instead, you could move the assignment to the end of the loop. 相反,您可以将分配移到循环的末尾。 That means, of course, that the first time around, the assignment hasn't happened.
当然,这意味着第一次没有分配。 So you may need to call it once outside the loop:
因此,您可能需要在循环外调用一次:
node = node -> next; // or some other initialisation of node
while(ind == 0 && node != null) {
doStuffWith(node);
node = node -> next;
}
Maybe you've been told about the DRY principle: "Don't repeat yourself", so you might feel uncomfortable about repeating node = node -> next
. 也许您已经被告知DRY原理:“不要重复自己”,所以对于重复
node = node -> next
可能会感到不舒服。 However it's an example of a very common pattern, for example: 但是,这是一个非常常见的模式的示例,例如:
int chars = stream.read(buffer);
while(chars != -1) {
doSomethingWith(buffer);
chars = stream.read(buffer);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.