错误:进程返回-1073741819(0xC0000005)C与指针有关吗?

时间:2018-02-14 22:04:40

标签: c pointers heap min dijkstra

我是code::blocks的新手以及它是如何工作的但是我正在将它用于uni的任务,基本上,它使用ADT和邻接列表实现dijkstra的算法,代码可以正常工作,我得到一个输出但我收到了错误

  

处理返回-1073741819(0xC0000005)

最小堆的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "graph.h"
#include "MinHeap.h"
#include "dynamicarraylist.h"
#include "singlelinkedlist.h"

#define CHAR_MAX 50
#define INFINITY 9999

///constructor function for the total heap, taking the capacity of the heap
///as an argument and returning the MinHeap struct
struct MinHeap* HeapConstructor(int V)
{
    //create and allocate memory for a new heap struct
    struct MinHeap* minHeap;
    minHeap = malloc(sizeof(struct MinHeap));
    //copy over the value of capacity and set numentities to 0
    minHeap->numentities = 0;

    //assign memory for the position pointer and for the node pointer
    minHeap->Node = malloc(V * sizeof(struct MinHeapNode));
    return minHeap;
}

struct MinHeapNode* HeapNodeConstructor(int distance,char* city)
{
    struct MinHeapNode* minHeapNode;
    minHeapNode = malloc(sizeof(struct MinHeapNode));

    minHeapNode->distance = distance;
    strcpy(minHeapNode->city,city);

    return minHeapNode;
}

struct ShortestPath* ShortestPathConstructor()
{
    //allocate enough memory for the struct
    struct ShortestPath* shortestPath;
    shortestPath = malloc(sizeof(struct ShortestPath));

    //initialize with sensible values
    shortestPath->distance = malloc(sizeof(int));
    shortestPath->parent = NULL;
    shortestPath->size = 0;
    return shortestPath;
} 

/// function to swap two nodes within a minimum heap, this allows us to sort
/// the heap, this is based on code found on stack overflow for swapping
/// two pointers found here: https://stackoverflow.com/questions/8403447/swapping-pointers-in-c-char-int
/// look at swap5 function of top answer
void NodeSwap(struct MinHeapNode** a, struct MinHeapNode** b)
{
    //create a temporary node to copy the value of a across to
    //using pointers so we dont have to return various structs
    struct MinHeapNode* temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

///function to heapify a min Heap and update position of all nodes within heap
///this is required for updating distances from vertex when carrying out dijkstra's algorithm
/// code for parts of the heapify function is based on psuedo code from the wikipedia article about
/// binary heaps found at: https://en.wikipedia.org/wiki/Binary_heap
void minHeapify(struct MinHeap* minHeap, int index)
{
     int smallest, left, right;
     smallest = index;
     left = (index * 2);
     right = (index * 2) + 1;

     //if we arent at the end of the heap and the left node is smaller than the node above it
     if(left <= minHeap->numentities && minHeap->Node[left]->distance < minHeap->Node[smallest]->distance)
     {
         //smallest becomes the left child node of the heap
         smallest = left;
     }
     // exact same procedure but they must be 2 separate if statements so     that the function compares both both numbers
     // in all cases
     if(right <= minHeap->numentities && minHeap->Node[right]->distance < minHeap->Node[smallest]->distance)
     {
         smallest = right;
     }

     //if the smallest node is different from before starting the function then the heap is not yet heapified
     if(smallest != index)
     {
         //swap nodes
         NodeSwap(&minHeap->Node[smallest],&minHeap->Node[index]);

         //recursive function so minHeapify is carried out within the function
         minHeapify(minHeap,smallest);
    }
}

/// simple function to check whether the heap is empty or not
/// so the function performing dijkstra's algorithm knows when to finish
/// takes the minHeap as parameters returning 0 if heap is empty and 1 if     it isn't
int HeapIsEmpty(struct MinHeap* minHeap)
{
    if(minHeap->numentities == 0)
    {
         return 0;
    }
    return 1;
}

///Builds our minimum heap using the graph and assigns the distances as infinite or
///0 for the source node then it heapifies until heap property is achieved
struct ShortestPath* BuildMinHeap(struct MinHeap* minHeap, struct List* graph, char* srccity,int V)
{
    struct ShortestPath* shortestpath = ShortestPathConstructor();
    int i;
    //for total size of the minHeap
    for(i = 0; i <= V; i++)
    {
        //if the source city and the city we're currently at are 0
        //distance from source is 0
        if(strcmp(srccity,graph->vertices[i].cityname) == 0)
        {
            minHeap->Node[minHeap->numentities + 1] = HeapNodeConstructor(0,srccity);
            shortestpath[shortestpath->size + 1].distance = 0;
            strcpy(shortestpath[shortestpath->size + 1].city,srccity);

        }
        //otherwise the distance is infinite
        else
        {
            minHeap->Node[minHeap->numentities + 1] = HeapNodeConstructor(INFINITY,graph->vertices[i].cityname);
            shortestpath[shortestpath->size + 1].distance = INFINITY;
            strcpy(shortestpath[shortestpath->size + 1].city,graph->vertices[i].cityname);
        }
        shortestpath->size++;
        minHeap->numentities++;
    }

    //moves through the heap making sure heap property is satisfied
    for(i = minHeap->numentities / 2; i > 0; i--)
    {
        minHeapify(minHeap,i);
    }
    return shortestpath;
}



///takes out and returns the minimum node from a heap given as an input
struct MinHeapNode* removeMin(struct MinHeap* minHeap)
{
    if(minHeap->numentities != 0)
    {
        //remove the root node of the minimum heap and store it
        struct MinHeapNode* root = minHeap->Node[1];
        //move the last element of the heap to the top
        minHeap->Node[1] = minHeap->Node[(minHeap->numentities) - 1];
        minHeap->numentities--;
        minHeapify(minHeap,1);
        return root;
    }
    else
    {
        printf("\nheap is empty \n");
    }

}

///search through the heap for given city name returning the index
///utilises a linear search algorithm
int HeapSearch(struct MinHeap* minHeap,char* cityname)
{
    int i;

    for(i = 1; i <= minHeap->numentities; i++)
    {
        if(strcmp(minHeap->Node[i]->city,cityname) == 0)
        {
            return i;
        }
    }
    return -1;
}

/// decreases key(value) stored within the node from what we defined infinity as being to the shortest currently available path from our source node
/// to the current node
void DecreaseKey(struct MinHeap* minHeap,int x,int newdistance)
{
    //find a return the index of our required city to decrease the key of
    int i = x;

    //compares new distance with currently stored distance and if bigger than the other function stops
    if(newdistance > minHeap->Node[i]->distance)
    {
        return;
    }
    else
    {
        //move to index node and update value of distance with distance
        minHeap->Node[i]->distance = newdistance;
    }

    //travel up tree until it is heapified by comparing the index node with its parent node
    while(minHeap->Node[i]->distance < minHeap->Node[i/2]->distance && i > 1)
    {
        //swap node with parent node
        NodeSwap(&minHeap->Node[i],&minHeap->Node[i/2]);
        //move to parent node
        i = i/2;
    }
}

void levelorderTraversal(struct MinHeap* minHeap)
{
    int i ;
    for(i = 1; i < minHeap->numentities; i++)
    {
        printf("\n %s %d ",minHeap->Node[i]->city, minHeap->Node[i]->distance);
    }
}

void shortestPathDisplay(struct ShortestPath* shortestPath)
{
     int i;
     printf("City    Distance From Source");
     for(i = 1; i < shortestPath->size;i++)
     {
         printf("\n%s \t\t %d",shortestPath[i].city,shortestPath[i].distance);
     }
}

///search the array list and return index of that search or a -1 if failure
///very important function used in AddEdge function, takes a List struct and a cityname
///as arguments
int ShortestPathSearch(struct ShortestPath* shortestPath, char* cityname)
{
    int i;

    //seaches from beginning to end of arraylist
    for(i = 1 ; i <= shortestPath->size; i++)
    {
        //strcmp() function compares two input strings, if they are the same it returns a 0
        if(strcmp(shortestPath[i].city,cityname) == 0)
        {
            // we want the index this vertex was found at
            return i;
        }
    }
    //if failure return -1
    return -1;
}

void dijkstra(struct List* graph,char* startcity)
{
    //two intermediate integer variables to find distance at various vertices to get minimum weight overall
    int V = graph->numcities;
    int added_distance;
    struct MinHeap* minHeap = HeapConstructor(V);
    struct ShortestPath* shortestPath = ShortestPathConstructor();


    //builds our minimum heap and heapifies it
    shortestPath = BuildMinHeap(minHeap,graph,startcity,V);
    ///shortestPathDisplay(shortestPath,V);
    ///levelorderTraversal(minHeap);



    while(minHeap->Node != NULL)
    {
        levelorderTraversal(minHeap);
        //extract shortest distance in heap
        struct MinHeapNode* shortestNode = removeMin(minHeap);


        printf("removed node is %s distance %d \n",shortestNode->city,shortestNode->distance);

        //searches for removed city within index and adds the current distance associated with this
        //city
        int z = ShortestPathSearch(shortestPath,shortestNode->city);
        added_distance = shortestPath[z].distance;
        printf("current dist from source: %d \n",added_distance);

        //searches for the index of the removed city within our adjacency list and stores it
        int u = ArrayListSearch(graph,shortestNode->city);
        //assigns a new struct of linkedNode type for traversing through adjacenct nodes
        struct linkedNode* adjListTraverse = graph->vertices[u].linkedList->head;
        //while not at end of list
        while(adjListTraverse != NULL)
        {
            printf("city: %s distance: %d \n",adjListTraverse->cityname,adjListTraverse->weight);
            //looks for the new adjacenct city within the heap and our output array
            int v = ShortestPathSearch(shortestPath,adjListTraverse->cityname);
            printf("v = %d \n",v);

            int x = HeapSearch(minHeap,adjListTraverse->cityname);
            printf("x = %d \n",x);

            //if it is in the array and the minHeap and the final distance is not finalised
            //if x = -1 city is not in heap anymore and can be skipped entirely

            if(adjListTraverse->weight + added_distance < shortestPath[v].distance)
            {
                shortestPath[v].distance = adjListTraverse->weight + added_distance;

                //update with new distances
                DecreaseKey(minHeap,x,shortestPath[v].distance);
            }
            adjListTraverse = adjListTraverse->next;

        }
        shortestPathDisplay(shortestPath);
        printf("\n");
    }
}

对不起,代码非常长,我一直试图找到问题的原因,我想这可能是因为没有分配内存的指针,但我找不到像这样的指针

0 个答案:

没有答案