[英]Segmentation fault in inititalizing a binary search tree after second insertion using a iterative insert function
在嘗試將第二個節點插入樹后,我遇到了分段錯誤,拋出了分段錯誤。 是由於initialize
函數還是insert
導致的分段錯誤? 我如何通過在 server.c 中進行更改來解決它?
客戶端.c文件:
int main()
{
Tree my_tree;
initialize(&my_tree);
while(1)
{
scanf("%d", &choice);
switch (choice)
{
case 1:
scanf("%d", &element);
insert(&my_tree, element);
break;
case 2:
exit(0);
}
}
return 0;
}
server.c 文件
typedef struct node
{
int data;
struct node *left;
struct node *right;
} Node;
typedef struct tree
{
Node *root;
} Tree;
void initialize(Tree *tree)
{
tree = (Tree*)malloc(sizeof(Tree));
tree->root = NULL;
}
void insert(Tree *tree, int data)
{
Node *temp = (Node*)malloc(sizeof(Node));
temp->left = temp->right = NULL;
temp->data = data;
if(tree->root == NULL)
tree->root = temp;
else
{
Node *prev,*curr;
prev = NULL;
curr = tree->root;
while(curr != NULL)
{
if(temp->data < curr->data){
prev = curr;
curr = curr->left;
}
if(temp->data >curr->data){
prev = curr;
curr = curr->right;
}
}
if(temp->data < prev->data)
prev->left = temp;
if(temp->data > prev->data)
prev->right = temp;
}
}
void initialize(Tree *tree)
{
tree = (Tree*)malloc(sizeof(Tree));
tree->root = NULL;
}
改成
void initialize(Tree *tree)
{
if (tree) {
tree->root = NULL;
}
}
當您為tree
分配內存時,您將使其指向新的內存位置,因此您的原始tree
的根節點不會被初始化為NULL
並且您還會引入內存泄漏。
不是初始化您在程序中實際使用的Tree
對象( main 中的tree
),而是分配一個新的Tree
對象並初始化該對象。 實際上, initialize
除了泄漏內存之外什么都不做。
要解決此問題,請更換
void initialize(Tree *tree)
{
tree = (Tree*)malloc(sizeof(Tree));
tree->root = NULL;
}
和
void initialize(Tree *tree)
{
tree->root = NULL;
}
OP指出還有第二個錯誤。 在這里我指出一個人不應該依賴陌生人的好意,並學習如何調試此類問題。
您可以使用調試器。
$ gcc -Wall -Wextra -pedantic -g a.c -o a && gdb --args ./a
GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
...
(gdb) r
Starting program: /tmp/ikegami/a
1
3
1
2
Program received signal SIGSEGV, Segmentation fault.
0x00005555555547b1 in insert (tree=0x7fffffffdda0, data=2) at a.c:39
39 if(temp->data >curr->data){
(gdb) print temp
$1 = (Node *) 0x555555756690
(gdb) print curr
$2 = (Node *) 0x0
(gdb) quit
A debugging session is active.
Inferior 1 [process 1433] will be killed.
Quit anyway? (y or n) y
另一種方法是在編譯程序時使用-fsanitize=address
。
$ gcc -Wall -Wextra -pedantic -g -fsanitize=address a.c -o a && ./a
1
3
1
2
ASAN:DEADLYSIGNAL
=================================================================
==1370==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x556253e76e87 bp 0x7ffe3a28e390 sp 0x7ffe3a28e360 T0)
==1370==The signal is caused by a READ memory access.
==1370==Hint: address points to the zero page.
#0 0x556253e76e86 in insert /home/ikegami/tmp/a.c:39
#1 0x556253e771af in main /home/ikegami/tmp/a.c:64
#2 0x7fc3bdadcb96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#3 0x556253e76b29 in _start (/tmp/ikegami/a+0xb29)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/ikegami/tmp/a.c:39 in insert
==1370==ABORTING
但是方法表明temp->data >curr->data
是罪魁禍首。 使用調試器,我們看到curr
是NULL
,所以curr->data
是有問題的。 現在您知道您需要弄清楚為什么curr
在您不希望它是 NULL 時為 NULL。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.