0

重複の可能性:
アレイを再初期化するとセグメンテーション違反が発生しますか?

形式(頂点、頂点b、重み)で指定された重みを持つエッジの入力でベルマンフォードとBFSを実行しています。最新のエッジを読み込むたびに、BFS (研究プロジェクトの一部) を実行します。

小さなセット、頂点が 8 ~ 10 の場合は完全に機能するように見えますが、頂点が 100 以上のセットを含む次のサンプル データにジャンプすると、再初期化時に失敗し、セグメンテーション違反が発生します...

まず、次のように初期化します。

for(i=0;i<numberVertices;i++)
        {
                vertexArray[i].v = i+1;
                vertexArray[i].adj = NULL;
                vertexArray[i].marked = 0;
                if(i==0)
                {
                        vertexArray[i].weight = 0;
                }
                else{
                        vertexArray[i].weight = 10000;
                }
        }

BFS を呼び出した後、BFS が再び機能するように、マークを 0 に再初期化する必要があるため、アレイを再初期化します。

numberUseful += BFS(vertexArray, q, u);

            for(i=0;i<numberVertices;i++)
            {
                    vertexArray[i].marked = 0;
            }

そして、行vertexArray[i].marked = 0;はセグメンテーション違反を引き起こします。

別の提案で、私はこのプログラムで valgrind を実行しました:

==6634== Memcheck, a memory error detector
==6634== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==6634== Using Valgrind-3.6.0 and LibVEX; rerun with -h for copyright info
==6634== Command: ./a.out 100S.txt
==6634==
==6634== Conditional jump or move depends on uninitialised value(s)
==6634==    at 0x400C13: checkonqueue (bfs.c:160)
==6634==    by 0x400B7F: BFS (bfs.c:142)
==6634==    by 0x40094A: main (bfs.c:103)
==6634==
==6634== Invalid write of size 4
==6634==    at 0x40096E: main (bfs.c:107)
==6634==  Address 0x4d00000041 is not stack'd, malloc'd or (recently) free'd
==6634==
==6634==
==6634== Process terminating with default action of signal 11 (SIGSEGV)
==6634==  Access not within mapped region at address 0x4D00000041
==6634==    at 0x40096E: main (bfs.c:107)
==6634==  If you believe this happened as a result of a stack
==6634==  overflow in your program's main thread (unlikely but
==6634==  possible), you can try to increase the size of the
==6634==  main thread stack using the --main-stacksize= flag.
==6634==  The main thread stack size used in this run was 10485760.
==6634==
==6634== HEAP SUMMARY:
==6634==     in use at exit: 3,448 bytes in 181 blocks
==6634==   total heap usage: 181 allocs, 0 frees, 3,448 bytes allocated
==6634==
==6634== LEAK SUMMARY:
==6634==    definitely lost: 0 bytes in 0 blocks
==6634==    indirectly lost: 0 bytes in 0 blocks
==6634==      possibly lost: 0 bytes in 0 blocks
==6634==    still reachable: 3,448 bytes in 181 blocks
==6634==         suppressed: 0 bytes in 0 blocks
==6634== Reachable blocks (those to which a pointer was found) are not shown.
==6634== To see them, rerun with: --leak-check=full --show-reachable=yes
==6634==
==6634== For counts of detected and suppressed errors, rerun with: -v
==6634== Use --track-origins=yes to see where uninitialised values come from
==6634== ERROR SUMMARY: 16120 errors from 2 contexts (suppressed: 6 from 6)

segfault (107) と同じ行と、checkonqueue 関数の一部である 160 行でエラーが発生したと言われています。

int checkonqueue(int * q, int value)
{
        int i = 0;
        for(i=0;i < max;i++)
        {
                if(q[i] == value)
                {
                        return 1;
                }
        }
        return 0;
}

どこif(q[i] == value)でメモリの問題が発生したかと言われました。

メモリの問題である可能性があると私が信じる理由は、それがより小さなセットで動作するという事実によるものです (またはそう思われます!)

valgrind を実際に使用する方法や、エラーを見つける方法を知っている場合は、非常に感謝しています!

BFS:

while(front != -1)
{
    u = dequeue(q);
    if(vertexArray[u-1].adj != NULL)
    {
        adjacent = vertexArray[u-1].adj;
        vertexArray[u-1].marked = 1;


        while(adjacent != NULL)
        {
            v = adjacent->v;
            if(distance[vertexArray[v-1].v-1] > distance[vertexArray[u-1].v-1] + adjacent->edgeWeight)
            {
                distance[vertexArray[v-1].v-1] = distance[vertexArray[u-1].v-1] +adjacent->edgeWeight;
                success = 1;

            }

            int check = 0;
            check = checkonqueue(q, v);
            if(check == 0 && vertexArray[v-1].marked == 0)
            {
                enqueue(q, v);
            }
            adjacent = adjacent->next;
        }
    }
}
return success;
4

0 に答える 0