2016-04-30 52 views
1

、私がアクセス違反読み取り場所0xCDCDCDCDエラーにアクセス違反読み取り場所0xCDCDCDCD

を取得しています。

ここでは、リンクされたリストの配列を扱っています。リンクされたリストに追加することが何か問題になると思います。私はこれで大丈夫ですが、メモリの割り当てに問題があると感じています。ここで

は私の構造体です:

グラフ:

typedef struct graph 
{ 
    int V; 
    int *state; 
    EdgeList *edges; 
} Graph; 

エッジ:

typedef struct edge 
{ 
    int toVertex; 
    int weight; 
} Edge; 

はEdgeList:

typedef struct edgeNode 
{ 
    Edge edge; 
    struct edgeNode *next; 
} *EdgeList; 

ここではそれをすべて実行します主な機能です。

main() 
{ 
    Graph myGraph; 
    scanf("%d", &(myGraph.V)); 
    myGraph.state = (int)malloc(myGraph.V*sizeof(int)); 
    myGraph.edges = (EdgeList*)malloc(myGraph.V*sizeof(EdgeList)); 
    int *inDegrees; 
    inDegrees = (int)malloc(sizeof(int)*myGraph.V); 

    /* Sets all array values to 0 */ 
    for (int counter = 0; counter < myGraph.V; counter++) 
    { 
     inDegrees[counter] = 0; 
    } 


    for (int i = 0; i < myGraph.V; i++) 
    { 
     int number_of_edges; 
     int input = 0; /*For that little experimental bit*/ 
     scanf("%d", &(myGraph.state[i])); 
     scanf("%d", &number_of_edges); 
     if (number_of_edges > 0) 
     { 
      for (int j = 0; j < number_of_edges; j++) 
      { 
       Edge newEdge; 
       scanf("%d,%d", &(newEdge.toVertex), &(newEdge.weight)); 
       inDegrees[newEdge.toVertex]++; 
       printf("%s%d\n", "\nOoh, new input for ", newEdge.toVertex); 

       /*insert at front*/ 
       EdgeList newNode = (EdgeList)malloc(sizeof (struct edgeNode)); 
       newNode->edge = newEdge; 

       newNode->next = myGraph.edges[i]; 
       myGraph.edges[i] = newNode; 


       /* Bit to calculate state.*/ 

       EdgeList current = myGraph.edges[i]; 

       while (current != NULL) 
       { 
        if (current->edge.toVertex == i) 
        { 
         input += (current->edge.weight)*(myGraph.state[i]); 
        } 
        current = current->next; 
       } 
      } 
      if (input > 0) 
      { 
       myGraph.state[i] = 1; 
      } 
      else 
      { 
       myGraph.state[i] = 0; 
      } 
     } 
    } 

    //print 
    for (int k = 0; k < myGraph.V; k++) 
    { 
     printf("\n%s%d%s", "In degrees for ", k, ": "); 
     printf("%d", inDegrees[k]); 
    } 

} 

特に、リンクされたリストのトラバーサル中にエラーが発生します。これは、上記のコードではありますが、私はここでそれをハイライト表示されます:私はむしろこだわっているので

EdgeList current = myGraph.edges[i]; 

while (current != NULL) 
{ 
    if (current->edge.toVertex == i) 
    { 
     input += (current->edge.weight)*(myGraph.state[i]); 
    } 
    current = current->next; 
} 

を誰が助けることができるならば、それは非常に高く評価されると思い。

+0

初期化されていないポインタが逆参照されることがあります。 – MikeCAT

+1

そのコードのどの行が実際にエラーを引き起こしたかを知ることは役に立ちます。あなたはデバッガの下でこれを実行しましたか? –

+0

はい、@ RyanBemrose。 VSが与える次のステートメントは、printf( "%s%d \ n"、 "現在のもの:"、current-> edge)行で停止します。toVertex); ' しかし、print文でテストしたので、whileループは少なくとも1回は実行されます。その後、それはクラッシュします。 – user3414510

答えて

2
    malloc()
  1. を介して割り当てられ、初期化されていないバッファの値がnewNode->next = myGraph.edges[i];newNode->edgeに割り当てられます。
  2. newNodecurrentmyGraph.edges[i] = newNode;EdgeList current = myGraph.edges[i];で設定します。
  3. malloc()が成功したとすると、currentはここではNULLではないため、ループに入ります。
  4. 1に設定された初期化されていない値はcurrentに割り当てられ、current = current->next;に割り当てられます。
  5. 定義されていない動作は、malloc()で割り当てられ、current != NULLで初期化されていないバッファ内の値を使用して呼び出されます。

、このエラーを修正例えば、このようにmyGraph.edgesを初期化するには:

myGraph.edges = (EdgeList*)malloc(myGraph.V*sizeof(EdgeList)); 
for (int i = 0; i < myGraph.V; i++) 
{ 
    myGraph.edges[i] = NULL; 
} 

また、malloc()から返されたポインタのintに有害なキャストを削除します。戻り値をポインタに明示的にキャストすることもnot considered as goodです。

+0

これは私がこの返事を見る前に、これが解決策であったかどうか、友人に尋ねたところです。とにかくおかげさまで、私は暗闇の中でただ刺していたので、それの背後にある理論を説明してくれてありがとう。 – user3414510

+0

この解決策は、事前に割り当てられた「エッジ」メモリブロックをゼロに初期化し、それらのノードのすべての「次の」ポインタをNULLに設定します。残りのコードは 'edges'リストの前に新しいノードを挿入しています。リストをたどることは、最初のノードのあとに他のノードが存在するにもかかわらず、 'next'が常にNULLであるため、最初に割り当てられたノードの後ろに触れることはありません。したがって、1)メモリを浪費するだけの場合はノードを事前に割り当てない、または2)ノードを使用できるようにメモリブロックをゼロにした後に「次の」ポインタを初期化する場合。 –

+0

@RemyLebeauノードはどこで無駄になると思いますか?これは将来のアドバイスですか? – MikeCAT

関連する問題