有问题的功能:
struct node* findNext(struct node *root, struct node *ldr, int *p) {
// Check if there are nodes in the tree.
if(p == 0){
if (root != NULL) {
// correct organ/bt combo
if(cmpOrgan(root, ldr) == 1){
if (strcmp(root->organ.name, ldr->organ.name) != 0){
if(cmpDates(root, ldr) == 1){
p = 1;
return root;
}
// The leader has been in longer then root
if(cmpDates(root, ldr) == 2){
return findNext(root->left, ldr, p);
}
}
else{
findNext(root->left, ldr, p);
findNext(root->right, ldr, p);
}
}
if(cmpOrgan(root, ldr) == 2){
return findNext(root->left, ldr, p);
}
if(cmpOrgan(root, ldr) == 3){
return findNext(root->right, ldr, p);
}
}
}
return NULL;
}
我想在这一部分突破这个递归函数:
if (strcmp(root->organ.name, ldr->organ.name) != 0){
if(cmpDates(root, ldr) == 1){
p = 1;
return root;
}
我尝试这样做的方法是扫描一个指向该函数的全局指针,并在希望函数中断后将其更改为1。我的目标是在断点处返回当前的根。这可能吗?我正在通过这样做初始化main中的指针:
int *p = 0;
当我尝试使用* p = 1设置值时,程序将崩溃。我很确定我错过了一些基本的指针,但我只是不知道什么是我还是新编码。谁能帮我?还有另一种比较简单的方法,我不知道吗?感谢您提前提供任何帮助。
答案 0 :(得分:3)
当您说int *p = 0
时,您正在创建一个空指针,NULL == 0
。
当您稍后尝试说*p = 1
时,您取消引用空指针,导致程序崩溃。
更准确地说,如果你真的想使用指针,你应该为你想要存储的int分配内存:
int *p = malloc(sizeof(int));
*p = 0;
然后你就有了放置int的地方。
或者,不要把它创建为指针 - 只需说
int p = 0;
然后使用p
传递&p
的地址,之前已经通过p
,将作业更改为*p = 1
。
三分之一的可能性是根本不会传递p
,只有一个全局变量p
可以被任何级别的函数更改。这通常被认为是错误的编码风格,但会完成你似乎想要做的事情。
最后,请注意,您不应该真正需要设置一个变量来突破递归 - 当您返回时,它应该只是继续返回您的函数调用堆栈,这通常可以布局至于不需要这样的标志变量。
特别是,您对findNext进行两次递归调用,其返回值被简单地丢弃(在第一个else块内)。这些似乎并没有真正完成任何事情,你最有可能更好地保持他们的返回值并使用它们来决定返回什么,或者更好的是,只调用一个,检查它的返回值,然后制作只在必要时才打电话。
答案 1 :(得分:0)
在findNext中,您执行了以下操作
p = 1
但是p是指向integer
的指针,因此您实际上将p
指向的地址设置为等于1.这可能会导致访问冲突和SIGSEGV。
这就是你的程序崩溃的原因。它尝试将数据写入应用程序地址空间之外的地址。做qaphla说的应该工作,虽然我自己没有测试过。
答案 2 :(得分:0)
代码的以下部分出现错误:
else{
findNext(root->left, ldr, p);
findNext(root->right, ldr, p);
}
在这两种情况下都会丢失返回值,这意味着任何路径中的任何成功搜索都将丢失。
类似下面的代码片段应该有效:
else{
struct node *rv = findNext(root->left, ldr, p);
if (rv) {
return rv;
} else {
return findNext(root->right, ldr, p);
}
也没理由调用cmpOrgan三次,每次调用cmpOrgan的递归中的任何级别都应该返回完全相同的值。同样适用于cmpDates。
因为每个路径都返回一个值。不再需要变量p。