正如我在评论中所说的,这需要检查的代码太多了,特别是当您
没有给我们足够的提示,从哪里开始看问题。
你能详细说明一下吗
为main中的根节点分配了内存,您没有初始化它
,我不确定我是否遵循。我想我保留了记忆,那为什么它会导致如此不稳定的行为呢。我想它有时需要垃圾值,对吗?
我简单地查看了代码,发现了相同的模式。你只是
分配内存,但在读取内容之前不初始化内存
已分配内存的。这会产生未定义的行为和你是什么
观察,有时工作,有时不工作,这是
未定义的行为。由于未定义行为的性质,它非常
很难预测会发生什么,有时几乎是不可能的。在大多数情况下
您所需要做的就是找到未定义行为的来源。
对你来说,我做的第一件事就是
malloc
呼叫并查看位置
初始化内存。你没有做到,所以我不再寻找更多
错误,因为这很可能是所有问题的根源。
分配内存时
马洛克
,你只能从
在操作系统中,无法保证内存在任何
这意味着内存有randon值。你在做什么
main
root = (struct node*) malloc(sizeof(struct node));
while(inputElement != 0) {
root = addElement(root,inputElement);
...
}
然后
addElement
是否:
struct node* addElement(struct node * rootNode, int inputElement){
if(rootNode->n == 0){
rootNode->keys[0] = inputElement;
...
} else {
rootNode = insertInTree(rootNode,inputElement);
...
}
}
如您所见,您已经为
root
节点,但
root->n
不是
初始化后,它的值是随机的,可能是0,但也可能是24或
-所以你的代码已经在做一些不可预测的事情了
查看代码,您无法知道
rootNode->keys[0] = inputElement;
已执行,或
rootNode = insertInTree(rootNode,inputElement);
.这就是问题所在
未定义行为的性质。如果幸运的话
rootNode->n
为0,则
功能可能正常工作。
你必须这样做
root = malloc(sizeof *root);
if(root == NULL)
{
fprintf(stderr, "No memory left\n");
return 1;
}
root->n = 0;
memset(root->keys, 0, sizeof root->keys / sizeof root->keys[0]);
for(size_t i = 0; i < sizeof root->children / sizeof root->children[0]; ++i)
root->children[i] = NULL;
while(inputElement != 0) {
root = addElement(root,inputElement);
...
}
-
Don't cast
malloc
-
检查
总是
,我的意思是
总是
的返回值
马洛克
/
realloc
-
如果你错过了,检查一下
总是
,我的意思是
总是
的返回案例
马洛克
/
realloc公司
-
避免使用
sizeof(struct node)
使用
sizeof *root
相反,生成代码
更加健壮。
-
别忘了
free()
内存。
-
万一你错过了,别忘了
免费()
内存
我还建议您创建一个函数,返回一个新的已分配+已初始化
节点,否则将一次又一次重复相同的代码。这适用于
你所有的
马洛克
呼叫。
当然,在您的情况下,可以通过使用
calloc
而不是
马洛克
。
分配
工作原理如下
马洛克
但它也设置了分配的
内存为0。这是一个很好的特性,因为如果你的记忆
已初始化为0和
NULL
指针
1.
,这节省了大量时间
你可以这样做
root = calloc(1, sizeof *root);
if(root == NULL)
{
fprintf(stderr, "No memory left\n");
return 1;
}
while(inputElement != 0) {
root = addElement(root,inputElement);
...
}
在整个代码中进行此更改,这将消除许多
未定义行为的来源。这并不意味着你所有的问题都是
但已解决。
脚注
1.
传说那里有很多建筑
无效的
是
未解释为0,因此使用
分配
用于初始化
无效的
指针可能会失败。
但我敢说任何人都能找到人们使用的商业上成功的建筑
在这种情况下,这些天的工作效率很高。