[英]Why is this segfaulting whilst building a binary tree?
我發現通過gdb在此代碼中的這一行是seg錯誤。 但是我似乎看不出為什么? 在發生段故障之前,它將運行6/7次。 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;
}
}
您執行temp = temp->next
但是temp->next
可能為nullptr
。 您必須先檢查它的非null才能嘗試訪問它的成員。
這是一些代碼,它將由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;
}
}
這是使用指針的替代版本:
struct mylist **pprev;
pprev = &liststart;
while (*pprev != NULL && (*pprev)->frequency <= newnode->frequency) {
pprev = &(*pprev)->next;
}
newnode->next = *pprev;
*pprev = newnode;
您的問題是您檢查temp
不為null,然后立即更新temp
,因此它可能又為null。
(我不喜歡temp
這個名字,因此在示例中將其更改為node
)
如果分解,這是最清楚的,因此:
while(ind == 0 && node != null) {
node = node -> next; // now node might be null
doStuffWith(node);
}
相反,您可以將分配移到循環的末尾。 當然,這意味着第一次沒有分配。 因此,您可能需要在循環外調用一次:
node = node -> next; // or some other initialisation of node
while(ind == 0 && node != null) {
doStuffWith(node);
node = node -> next;
}
也許您已經被告知DRY原理:“不要重復自己”,所以對於重復node = node -> next
可能會感到不舒服。 但是,這是一個非常常見的模式的示例,例如:
int chars = stream.read(buffer);
while(chars != -1) {
doSomethingWith(buffer);
chars = stream.read(buffer);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.