c - 访问了未知的 NULL 值
问题描述
这是 AVL 树的部分程序,但现在它更像是一个 BST
#include <stdio.h>
#include <stdlib.h>
#include<conio.h>
typedef struct node node;
struct node
{
int data;
int height;
node *left;
node *right;
} *root = NULL, *temp = NULL;
int max(int n1, int n2)
{
return n1 > n2 ? n1 : n2;
}
node *new_node(int value)
{
temp = (node *)malloc(sizeof(node));
temp->data = value;
temp->left = NULL;
temp->right = NULL;
temp->height = 0;
return temp;
}
int get_height(node *x)
{
if (x == NULL)
{
return -1;
}
return x->height;
}
node *insert(node *r, int value)
{
if (r == NULL)
{
return new_node(value);
}
else
{
if (value < r->data)
r->left = insert(r->left, value);
else
r->right = insert(r->right, value);
int height = max(get_height(r->left), get_height(r->right)) + 1;
}
void inorder(node *r)
{
if (r == NULL)
return;
inorder(r->left);
printf("node = %d, height = %d\n", r->data, r->height);
inorder(r->right);
}
void main()
{
root = insert(root, 10);
root = insert(root, 20);
inorder(root);
}
该程序的输出如下,因为我没有访问任何 NULL 值 -
node = 10, height = 1
node = 20, height = 0
仅添加一行后,我正在访问一个 NULL 值
#include <stdio.h>
#include <stdlib.h>
#include<conio.h>
typedef struct node node;
struct node
{
int data;
int height;
node *left;
node *right;
} *root = NULL, *temp = NULL;
int max(int n1, int n2)
{
return n1 > n2 ? n1 : n2;
}
node *new_node(int value)
{
temp = (node *)malloc(sizeof(node));
temp->data = value;
temp->left = NULL;
temp->right = NULL;
temp->height = 0;
return temp;
}
int get_height(node *x)
{
if (x == NULL)
{
return -1;
}
return x->height;
}
node *insert(node *r, int value)
{
if (r == NULL)
{
return new_node(value);
}
else
{
if (value < r->data)
r->left = insert(r->left, value);
else
r->right = insert(r->right, value);
int height = max(get_height(r->left), get_height(r->right)) + 1;
int balance_factor = get_height(r->left)- get_height(r->right); // extra line added
}
}
void inorder(node *r)
{
if (r == NULL)
return;
inorder(r->left);
printf("node = %d, height = %d\n", r->data, r->height);
inorder(r->right);
}
void main()
{
root = insert(root, 10);
root = insert(root, 20);
inorder(root);
}
现在我的程序只是挂起,它不是一个无限的调用/循环。这肯定是一个 NULL 值访问。但这怎么可能呢?
解决方案
通过论坛/问答进行调试永远不会有效。使用调试器:
例如在https://onlinegdb.com/S1ZansZNU
Reading symbols from a.out...done.
/usr/share/gdb/gdbinit: No such file or directory.
(gdb) run
Starting program: /home/a.out
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400703 in inorder (r=0xffffffff) at main.c:62
62 inorder(r->left);
(gdb)
r
不是 NULL,但也不是有效地址。
问题显然在:
root = insert(root, 10);
当 insert 没有显式返回值时
推荐阅读
- python - mysql.connector.errors.InternalError:使用“DELETE”时发现未读结果错误
- python - Kivy 弹出窗口显示与主屏幕相同的按钮
- regex - 如何在 PowerShell 中使用正则表达式将动态字符串格式化为数组?
- c# - FluentValidation 不适用于不同的库
- c# - Unity:无法让游戏对象生成
- google-apps-script - 将列值从一个电子表格复制到另一个电子表格,仅添加必要的行
- docker - 可以将 docker 注册表从一台机器复制到另一台机器吗?
- javascript - fileReader.onload 不会第二次运行,即使选择了不同的文件
- alexa-skills-kit - 上传清单文件失败
- java - 如果元素在 java 中不存在,则添加该元素