-3

私はこの課題に取り組んでおり、C でプログラミングするのはまだ初めてですが、メモリ参照とポインターの使用法をよりよく把握していると思いました...

私がやろうとしているのは、ソートされた配列からバランスの取れたバイナリ ツリーを作成することです。ツリー構築関数を呼び出そうとすると、セグメンテーション違反が発生します。その関数呼び出しをそのままにして、配列を出力するだけで、すべてがコンパイルされ、予想される出力で正常に実行されます。

私はこのように構築されたツリーのノードを持っています:

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*/
    }
}

main() に戻り、配列 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( "in Balance" ) ステートメントを見ることさえできず、 root = balance() 関数呼び出しの上の数行以内に他の printf() を配置すると、それらは実行されません。セグメンテーション違反の前にも印刷されません。多分それは私が理解していないコンパイラの動的なものですか?

4

1 に答える 1

3

ptr関数で変数がどのように割り当てられているかわかりませんbalanceptr->valueポインターをどこかに向けない限り、常に null の逆参照が発生します (ポインターにメモリを割り当てるか、既存のメモリを指すようにします)。

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

mid = first + (last - first)/2;
ptr->value = n[mid]; 
于 2012-04-23T09:26:49.193 に答える