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 に変更することです。私の目標は、ブレーク ポイントで現在のルートを返すことです。これは可能ですか?これを行うことで、メインのポインターを初期化しています。

int *p = 0;

*p = 1 で値を設定しようとすると、プログラムがクラッシュします。私はポインタで基本的な何かが欠けていると確信していますが、コーディングにはまだ慣れていないので何がわかりません。誰でも私を助けることができますか?私が気付いていない、これを行うよりも簡単な方法はありますか?事前に助けてくれてありがとう。

4

3 に答える 3

3

あなたが言うときint *p = 0、あなたはヌルポインタを作成していますNULL == 0.

後で と言おうとすると*p = 1、null ポインターが逆参照され、プログラムがクラッシュします。

より正確には、本当にポインターを使用する場合は、そこに格納する int にメモリを割り当てる必要があります。

int *p = malloc(sizeof(int));
*p = 0;

そして、intを置く場所があります。

または、ポインターとして作成する必要はありません。

int p = 0;

次に、 のアドレスを に渡し、以前に渡した場所にpを使用して、割り当てを に変更します。&pp*p = 1

3 つ目の可能性は、まったくパスせず、任意のレベルで関数によって変更できるpグローバル変数を持つことです。pこれは一般的に悪いコーディング スタイルと考えられていますが、あなたがやろうとしているように見えることは達成できます。

最後に、再帰から抜け出すために変数を実際に設定する必要はないことに注意してください。戻るときは、単に関数呼び出しのスタックをずっと返し続ける必要があります。そのようなフラグ変数が必要です。

特に、戻り値が単純に破棄される findNext への 2 つの再帰呼び出しを行います (最初の else ブロック内)。これらは実際には何も達成していないようであり、戻り値を保持し、それらを使用して何を返すかを決定するか、さらに良いことに、1 つだけを呼び出し、その戻り値を確認してから、 2 回目の呼び出しは、必要な場合にのみ行います。

于 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 を 3 回呼び出す理由はありません。再帰のどのレベルでも、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 に答える