-2

セグメンテーション違反のため、これをコンパイルできません。ツリー象限を使用して最大容量を表示すると、そのエラーが発生します。奇妙なことに、それは関数Quadrant内では機能しますが、挿入ではDotは機能しません。ツリーの作成機能は問題なく、象限も問題ありません。しかし、ツリー象限内の何かにアクセスしようとすると(象限はNULLではないので、以前に確認しました)、セグメンテーション違反の問題通知が実行され続けます。非常に単純なエラーだと思いますが、それが何であるかわかりません。私はインターネットで検索しようとしましたが(何も見つかりませんでした)、この完全なプログラムを実行する時間が不足しています(そして私はこれに何時間も立ち往生しています)。誰か助けてもらえますか?コードは次のとおりです。

    #include <stdlib.h>
    #include <stdio.h>
    #include <float.h>
    #include <limits.h>



        typedef struct dot{
            double x;
            double y;
        }Dot;


        typedef struct quadrant{
            int max_capacity, used_capacity;
            Dot max,min;
            Dot * dots_;
        }Quadrant;


        typedef struct quad_node * Quad_node_Pointer;

        typedef struct quad_node{
            Quadrant * key;
            Quad_node_Pointer child[4];
            Quad_node_Pointer father;
        }Quad_node;


        typedef struct tree{
            Quad_node * end_;
            Quad_node * start_;
        }Tree;





        void insert_dot(Tree * A, Dot b){
            printf("lalala\n");
            Quad_node * Aux, *Aux2, * New_leafs[4];
            Dot min_aux,max_aux;
            int i;
            Aux=(Quad_node_Pointer) malloc (sizeof(Quad_node));
            Aux2=(Quad_node_Pointer) malloc (sizeof(Quad_node));
            printf("lalala\n");
            //Here's the segfault line:
            printf("this doesnt works %i",A->start_->key->max_capacity);

        void Create_quadrant (Quadrant * A, int capacity,  Dot max, Dot min){
            A=(Quadrant*)malloc(sizeof(Quadrant));
            A->dots_ = (Dot*) malloc (capacity * sizeof(Dot));
            int i;
            for (i=0;i<capacity;i++){
                A->dots_[i].x=-1;
                A->dots_[i].y=-1;
            }
            A->max_capacity=capacity;
            //But here it works perfectly. What's the diference from the other that do 
            //a segfault?
            printf("\n this works \n %i \n",A->max_capacity);
            A->used_capacity=0;
            A->max.x=max.x;
            A->max.y=max.y;
            A->min.y=min.y;
            A->min.x=min.x;
            }

    void Create_tree (Tree * A, int capacity){
        int i;
        Dot max,min;
        max.x=DBL_MAX;
        max.y=DBL_MAX;
        min.x=0;
        min.y=0;
        A->end_ = (Quad_node_Pointer) malloc (sizeof(Quad_node));
        A->start_=(Quad_node_Pointer) malloc (sizeof(Quad_node));
            for (i=0;i<4;i++){
                A->start_->child[i]=A->end_;
            }
            A->start_->father=A->end_;

        Create_quadrant(A->start_->key,capacity,max,min);
    }

例として、メインを次に示します。

int main(int argc, char *argv[])
{
    Tree * A;
    int i;
    A = (Tree*) malloc (sizeof(Tree));
    Dot b,teste[10];
    b.x=5.0;
    b.y=6.0;
    Create_tree(A,8);
    for (i=0;i<10;i++){
        teste[i].x=(double)2.0*i;
        teste[i].y=(double)2.0*i;
        insert_dot(A,teste[i]);
    }
    insert_dot(A,b);
    free(A);
    return EXIT_SUCCESS;
}

読んだり、助けてくれてありがとう。

編集:覚えておいてください、私は忘れました。ドット挿入機能がいっぱいではありません。焦点はセグメンテーション違反の問題です。そして、メインは、完全な機能に基づいて実行されている例からのものです。ご迷惑をおかけして申し訳ありません。しかし、私の問題は、この奇妙なセグメンテーション違反にあります。関数の残りの部分は問題ないと思います。質問をより単純にするために省略しました(関数の残りの部分とは関係ありません)。

4

2 に答える 2

2

行きましょう...間にある無関係な行を無視して、関連するコードを表示します。

まず、ストレージを割り当ててツリーを初期化します...

A = (Tree*) malloc (sizeof(Tree));
Create_tree(A,8);

Create_tree関数は次のものを初期化しますA

    A->end_ = (Quad_node_Pointer) malloc (sizeof(Quad_node));
    A->start_=(Quad_node_Pointer) malloc (sizeof(Quad_node));
    for (i=0;i<4;i++){
        A->start_->child[i]=A->end_;
    }
    A->start_->father=A->end_;

さて、これでA->start_A->end_に4つの子ポインタを設定したことを除いて、初期化されていないストレージがありますA->start_->child[]

この時点で、を呼び出しCreate_quadrantて初期化し、初期化されA->start_->keyていないポインタを渡します。

    Create_quadrant(A->start_->key,capacity,max,min);

関数宣言は次のとおりです。

void Create_quadrant (Quadrant * A, int capacity,  Dot max, Dot min);

新しく初期化された象限をに戻す方法はありませんA->start_->key。その関数の最初の行がこれを行うので、明らかにこれを行いたいと思います。

        A=(Quadrant*)malloc(sizeof(Quadrant));

これは、これまでのコードのパラダイムを破ります。データの割り当てを担当し、関数を呼び出してデータを初期化します。init関数が関数内に割り当てられたポインターを返すようにしたい場合は、それを返すか、doubleポインターを渡す必要があります。

したがって、オプション1は次のとおりです。

Quadrant * Create_quadrant (int capacity,  Dot max, Dot min)
{
    A=(Quadrant*)malloc(sizeof(Quadrant));
    //...
    return A;
}

// Called like this:
A->start_->key = Create_quadrant( capacity, max, min );

そしてオプション2は次のとおりです。

void Create_quadrant (Quadrant ** pA, int capacity,  Dot max, Dot min)
{
    A=(Quadrant*)malloc(sizeof(Quadrant));
    // ...
    *pA = A;         
}

// Called like this:
Create_quadrant( &A->start_->key, capacity, max, min );

オプション0は、これまで使用してきた規則を継続することであることに言及するのを忘れました。

// Called like this:
A->start_->key = (Quadrant*)malloc(sizeof(Quadrant));
Create_quadrant( A->start_->key, capacity, max, min );

// And obviously you DON'T malloc a new A inside Create_quadrant().
于 2013-03-21T03:21:11.707 に答える
0

私の推測ではmalloc、sに十分なスペースを確保していないQuadrantのは、メモリ内にaが占めるスペースと同じだけのスペースを与えているだけQuad_nodeであり、おそらくQuad_nodesがsよりも少ないスペースを占めるためQuadrantです。

于 2013-03-21T03:04:13.563 に答える