1

有问题的功能:

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 设置值时,程序将崩溃。我很确定我缺少指针的基本知识,但我只是不知道什么,因为我还是编码新手。谁能帮我?还有另一种我不知道的更简单的方法吗?感谢您提前提供任何帮助。

4

3 回答 3

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 块内)。这些似乎并没有真正完成任何事情,你很可能会更好地保持它们的返回值并使用它们来决定返回什么,或者更好的是,只调用一个,检查它的返回值,然后制作仅在必要时进行第二次调用。

于 2013-11-08T02:14:43.007 回答
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。

于 2013-11-08T02:56:30.917 回答
0

在 findNext 中,您执行了以下操作

p = 1

但是 p 是指向 an 的指针integer,因此您实际上将p指向的地址设置为等于 1。这可能会导致访问冲突和 SIGSEGV。

这就是您的程序崩溃的原因。它尝试将数据写入应用程序地址空间之外的地址。尽管我自己没有测试过,但按照 qaphla 所说的去做应该可以。

于 2013-11-08T02:22:37.583 回答