Подтвердить что ты не робот

Ошибка сегментации перед основным

поэтому у меня возникла проблема, когда каким-то образом мой код вызывает ошибки сегментации, прежде чем какой-либо из моих основных работает. Я никогда раньше этого не делал, и вряд ли у меня есть опыт кодирования на четверть, поэтому я не уверен, есть ли что-то, что я делаю неправильно. Все компилируется, по крайней мере, на моем компьютере, но при его запуске моя цель никогда не достигается.

Контекст: я пытаюсь связать вершины и края в матрице смежности, а затем использовать алгоритм Prim для построения MST, но для более позднего. Я построил файл заголовка, который первоначально содержал только вызовы typdef для структур и функций. Однако я переключил определения структуры в файл заголовка, потому что я получал ошибки памяти; поэтому почему я думаю, что есть проблема с структурами.

graph.h:

//Leland Wong 00000897031
//graph header file



#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>

#ifndef GRAPH_H
#define GRAPH_H

typedef struct vertex
{
    double longitude;
    double latitude;
    char city[30];
    int index;
    int visited; //0: not visited, 1: visited, 2: visited
    struct edge* nexte;
    struct vertex* nextv;
    double projected;
}VERTEX;


typedef struct edge
{
    struct vertex* start;
    struct vertex* destination;
    double distance;
    struct edge* nexte;
}EDGE;


typedef struct graph
{
    struct vertex* list[756];
    struct edge* matrix[756][756];
}GRAPH;


/*
typedef struct vertex VERTEX;
typedef struct edge EDGE;
typedef struct graph GRAPH;
*/

double findDistance(VERTEX* v1, VERTEX* v2); //compute the distance between two locations
EDGE* connect(VERTEX* v1, VERTEX* v2); //connects two vertices and returns the connecting EDGE
GRAPH primMatrix(GRAPH *g); //connects all vertices using Prim Algorithm in an adjacency matrix
//void lPrimConnect(VERTEX v); //connects all vertices using Prim Algorithm in an adjacency list
EDGE* findSmallestEdge(VERTEX v, GRAPH *g); //finds the smallest EDGE connected to v


#endif

graph.c: содержит реализации всех моих функций

//functions

//computes the distance between v1 and v2
double findDistance(VERTEX* v1, VERTEX* v2)
{
    printf("findDistance");
    double long1 = v1->longitude;
    double long2 = v2->longitude;
    double lat1 = v1->latitude;
    double lat2 = v2->latitude;
    double distance = 0;

    if(long1 < 0)
        long1 += 360;
    if(long2 < 0)
        long2 += 360;

    distance = powf((long1-long2), 2) + powf((lat1 - lat2), 2);
    distance = sqrt(distance);
    return distance;
}

//creates and returns an edge that connects v1 and v2
EDGE* connect(VERTEX* v1, VERTEX* v2)
{
    printf("connect");
    EDGE *new; 
    new->start = v1;
    new->destination = v2;
    new->distance = findDistance(v1, v2);
    return new;
}


//finds smallest edge connected to v in GRAPH g
EDGE* findSmallestEdge(VERTEX v, GRAPH *g)
{
    printf("findSmallestEdge");
    EDGE *tempe;
    int i, index;
    index = v.index;

    //set tempe equal to the first edge connected to v
    tempe = g->matrix[index][0];
    //find smallest edge connected to v
    for(i = 0; i < 756; i++)
    {
        if(g->matrix[index][i] -> distance < tempe->distance && g->list[index]->visited == 0)
        {
            tempe = g->matrix[index][i];
        }
    }
    return tempe;
}

//creates an MST out of GRAPH g using Prim algorithm
GRAPH primMatrix(GRAPH *g)
{
    printf("primMatrix");
    GRAPH new; // = malloc(sizeof(GRAPH));
    EDGE *smallest;
    EDGE *tempe;
    int i, x;
    i = 1;
    x = 0;

    new.list[0] = g->list[0];   //add root node to MST
    g->list[0]->visited = 2;
    smallest = findSmallestEdge(*new.list[0], g); 
    new.matrix[0][smallest->destination->index] = smallest;
    //MST will contain all 756 nodes, so run this 755 times to ensure all nodes are reached
    while(i < 756)
    {
        x = 0;
        smallest = findSmallestEdge(*new.list[i], g);
        //i = number of vertices already reached
        while(x < i)
        {
            tempe = findSmallestEdge(*new.list[x], g);
            if(tempe -> distance < smallest -> distance)
            {
                smallest = tempe;
            }
            x++;
        }
        new.list[i] = smallest -> destination;
        smallest -> destination -> visited = 2;
        new.matrix[smallest->start->index][smallest->destination->index] = smallest;
        i++;
    }
    return new;
}

graphmatrixmain.c: моя основная функция, которая строит графики

#include "graph.h"

int main(int argc, char* argv[])
{
    FILE *fp;
    static GRAPH g;
    char buffer[200];
    int i, j;
    char city[30];
    char *long1;
    char *lat1;

    if(argc == 1)
    {   
        printf("could not open file\n");
        return 0;
    }

    else
        fp = fopen(argv[1], "r");

    //read in line of data from txt file, build a new vertex, and insert into list
    while(fgets(buffer, 200, fp) != NULL)
    {
        VERTEX *new =  malloc(sizeof(VERTEX)); 
        printf("%s", buffer);
        sscanf(buffer, "%s %s %s", city, long1, lat1);
        //sscanf(buffer, "%[^\t]\t%[^\t]\t%s", city, long1, lat1); 
        printf("scanned in data\n");
        new->longitude = atof(long1);
        new->latitude = atof(lat1);
        new->index = i;
        g.list[i] = new;
        printf("%s: (%lf, %lf)", new->city, new->longitude, new->latitude);
        i++;
    }
    //create EDGE and make connects between every VERTEX in list
    for(i = 0; i < 756; i++)
    {
        for(j = 0; j < 756; j++)
        {
            g.matrix[i][j] = connect(g.list[i], g.list[j]);
            if(j == 0)
            {
                g.list[i]->nexte = g.matrix[i][j];
            }
        }
    }
    return 0;
}

В случае необходимости, это файл, в который я читаю: city.txt он содержит всего 756 записей, но поскольку размер кода не должен быть релевантным

Shanghai    121.47  31.23
Bombay  72.82   18.96
Karachi 67.01   24.86
Buenos Aires    -58.37  -34.61
Delhi   77.21   28.67
Istanbul    29  41.1
Manila  120.97  14.62
Sao Paulo   -46.63  -23.53
Moscow  37.62   55.75
4b9b3361

Ответ 1

У меня возникла проблема, когда каким-то образом мой код вызывает ошибки сегментации, прежде чем какой-либо из моих основных работает.

Обычно это означает, что структуры данных, которые ваш main пытается разместить в области автоматического хранения, переполняют стек. В вашей ситуации похоже, что GRAPH является подходящим подозреваемым для этого: у него есть 2D-массив с указателями 571536, который вполне может переполнить стек до того, как ваш main получит шанс начать.

Одним из решений этой проблемы будет перемещение GRAPH в область static: так как вы выделяете ее в main, это будет только один экземпляр этого файла, поэтому объявление его static должно исправить проблема:

static GRAPH g;

Вы также можете выделить его в динамической области с помощью malloc, но в этом случае это, вероятно, не имеет значения.

Ответ 2

Ваша проблема заключается не в "перед основным", как вы заявляете, а в первых нескольких строках вашей программы. Вы не инициализируете fp, поэтому он может идти куда угодно. У вас также есть ошибки памяти в вашем цикле с помощью new. Вам нужно скопировать значение во вновь выделенную память.

Вы не можете видеть printf в своем коде, потому что вывод буферизирован, и ваш код сработает до сброса буфера. Если вы положите exit(0) сразу после своего printf("error");, вы увидите, что он работает.