2012-04-23 7 views
-2

私はこの課題に取り組んでいますが、私はまだCでプログラミングするのは初めてですが、メモリ参照とポインタの使用...ソートされた配列(segfault)からバランスのとれたバイナリツリーを構築するのに間違いが見つかりません

私がしようとしているのは、ソートされた配列からバランスのとれたバイナリツリーを作成することです。ツリー構築機能を呼び出そうとすると、セグメンテーションフォルトが発生します。その関数呼び出しを残して配列を出力するだけで、すべてがコンパイルされ、期待される出力でうまく動作します。

typedef struct leaf{ 
    int value; 
    struct leaf* left; 
    struct leaf* right; 
} LEAF; 

マイソート/ツリー構築関数ライブラリ::私はこのように構築された木の私のノードを持っている

メインで

LEAF* balance(int n[], int first, int last){ 
    int mid; 
    LEAF* ptr = NULL; 
    printf("in Balance"); 
    if (first > last) return NULL; 

    mid = first + (last - first)/2; 
    ptr->value = n[mid]; 

    ptr->left = (balance(n, first, mid-1)); 
    ptr->right = (balance(n, mid+1, last)); 

    return ptr;   
} 
void ins (int* n, int length){ //Don't THINK the problem lies here, 
            I've used the algorithm before and can 
            print out the sorted array 
    int i, j, key; 

    for(i = 0; i < length; i++){/*all indexes*/ 
      key = n[i]; /*pick out index and store in variable*/ 
      for(j = i-1; j >= 0; j = j-1){/*all objects left of i*/ 
        if (n[j] < key) break;/*stop and insert*/ 
        n[j + 1] = n[j];/*shifting all objects left*/ 
      } 
      n[j + 1] = key;/*insertion expression*/ 
    } 
} 

バックを()、私は私の配列を作成しますn []を呼び出してbalance()を呼び出します。

int main (void){ 
/****** initializations */ 
    int* n; 
    char buffer[20]; 
    FILE* fp; 
    int numMax = 5; 
    int lastIndex = 0; 
    int j; 
    char* filename = "numbers.txt"; 
    LEAF* root = NULL; 
    n = malloc (numMax * sizeof(int*)); 

    if ((fp = fopen(filename, "r")) == NULL){ 
      printf("cannot open %s\n", filename); 
      exit(1); 
    } 

/****** allocating storage array and inputting */ 
    printf("initial array size: %d", numMax); 
    while(fgets(buffer, sizeof(buffer), fp) != NULL){ 
      n[lastIndex] = atoi(buffer); 
      lastIndex++; 

      if (lastIndex == numMax){ /*When max num reached, double allocation*/ 
        numMax = numMax * 2; 
        if ((n = realloc(n, numMax * sizeof(int))) == NULL){ 
          printf("Cannot allocate more mem."); 
          exit(1); 
        } 

        printf("\nReached limit... increasing array to %d possible indexes.", numMax); 
      } 

    } 
    lastIndex--; 

/****** sort*/ 
    ins(n, lastIndex+1); 

/****** build tree*/ 
    root = balance(n, 0, lastIndex); 

ここには、おそらく私の問題を解決する。私はこのポストにかなり多くのコードを載せました。予想外のどこかでうんざりしてしまった可能性があります。私はそれがおそらく私が気まずい気分にさせる本当に簡単な解決策だと思っています。私は気分が悪いと思う、私は間違いを2回する可能性は低い!

しかし、私はprintf( "balance in")ステートメントを見ることができません。また、root = balance()関数の上に2行以内に他のprintf()それらはセグメンテーションの前にも印刷されません。おそらく、それは私が理解していないコンパイラのいくつかの動的ですか?

+1

にはこちら:(例えば 'gccの-Wall -g' Linux上で)** **すべての警告とデバッグinformatiopnでコンパイルし、何の警告は、コンパイラによって与えられていないまで、あなたのソースコードを改善します。 **デバッガ**を使用する(例えば、Linuxでは 'gdb')。 'printf'書式文字列を' \ n'で終わらせます(あるいは適切に 'fflush'を呼び出します)。 –

+0

私はgdbの使い方を学んできました。私はいくつかのチュートリアルビデオを見て、それについて少しお読みください。そのようなデバッガの使い方の大部分は私の頭の中を少し行きます... コンパイルする限り、コマンドラインスイッチ-pedanticと-std = c89を使用しています。これと-Wall -gの違いは何ですか? – fmdub

+0

'-Wall'はほぼすべての警告を表示します(' -Wextra'はさらに多くを与えます)。 '-g'はオブジェクトファイル内の' gdb'に便利なデバッグ情報を生成します。 –

答えて

3

ptr変数がbalance関数でどのように割り当てられているのかわかりません。 ptr->valueは、ポインタをどこかに指していなければ(そのためにいくつかのメモリを割り当てるか、既存のメモリを指すようにしないかぎり)、常に逆参照を行います。

LEAF* ptr = NULL; 
printf("in Balance"); 
if (first > last) return NULL; 

mid = first + (last - first)/2; 
ptr->value = n[mid]; 
+0

それは答えです... *一口* 本当に愚かな間違い。私もそれを試す必要はなかった、私はちょうど私の手に私の頭を設定し、自分自身を蹴った。 – fmdub

+0

これはプログラミングがあなたの愚かな間違いを見つけることの学習の問題であるという認識の最初の部分です: –

+0

私はあなたが絶対に正しいと思っています。この分野の人々はすべて理解しているようです私たちはすべて愚かな間違いをするつもりです。今まで私が見たことから、人々はあなたを相手にしているように見えません。 – fmdub

関連する問題