c - ssmtp - xdotool segmentation fault




Segmentierungsfehler vor dem Haupt (2)

Also bin ich auf ein Problem gestoßen, bei dem mein Code irgendwie Fehler in der Segmentierung verursacht, bevor einer meiner Hauptrechner tatsächlich läuft. Ich habe das noch nie zuvor erlebt und ich habe kaum ein Viertel der Programmierkenntnisse, also bin ich mir nicht sicher, ob ich etwas falsch mache. Alles kompiliert sich, zumindest auf meinem Computer, aber wenn ich es laufen lasse, wird mein Hauptrechner nie erreicht.

Kontext: Ich versuche, Eckpunkte und Kanten in einer Adjazenzmatrix zu verbinden und dann Prims Algorithmus zu verwenden, um eine MST zu erstellen, aber das ist für später. Ich habe eine Header-Datei erstellt, die ursprünglich nur Typdef-Aufrufe für die Strukturen und die Funktionen enthielt. Allerdings habe ich die Strukturdefinitionen in die Header-Datei gewechselt, weil ich Speicherfehler bekommen habe. Deshalb denke ich, dass es ein Problem mit den Strukturen gibt.

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's Algorithm in an adjacency matrix
//void lPrimConnect(VERTEX v); //connects all vertices using Prim's Algorithm in an adjacency list
EDGE* findSmallestEdge(VERTEX v, GRAPH *g); //finds the smallest EDGE connected to v


#endif

graph.c: enthält die Implementierungen aller meiner Funktionen

//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's 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: Meine Hauptfunktion, die die Graphen erstellt

#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;
}

Falls es notwendig ist, ist dies die Datei, die ich einlese von: cities.txt es enthält 756 Einträge insgesamt, aber soweit der Code betroffen ist Größe sollte nicht relevant sein

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

Ich bin auf ein Problem gestoßen, bei dem mein Code irgendwie Segmentierungsfehler verursacht, bevor einer meiner Hauptläufe tatsächlich läuft.

In der Regel bedeutet dies, dass die Datenstrukturen, die Ihr main in den automatischen Speicherbereich legen will, den Stapel überlaufen. In Ihrer Situation sieht es so aus, als wäre der GRAPH ein geeigneter Verdächtiger, um genau das zu tun: Er hat ein 2D-Array mit 571536 Zeigern, das den Stack sehr gut überfluten könnte, bevor Ihre Hauptinitiative starten kann.

Eine Lösung für dieses Problem wäre, den GRAPH in den static Bereich zu verschieben: Da Sie ihn im main zuweisen, wird er ohnehin nur eine Instanz davon sein. Wenn Sie ihn also statisch deklarieren, sollte das Problem behoben werden:

static GRAPH g;

Vielleicht möchten Sie es auch im dynamischen Bereich mit malloc zuweisen, aber in diesem Fall spielt es wahrscheinlich keine Rolle.


Ihr Problem ist nicht "vor dem Haupt", wie Sie sagen, sondern in den ersten Zeilen Ihres Programms. Sie initialisieren nicht fp , also könnte es überall gehen. Sie haben auch Speicherfehler in Ihrer Schleife mit new . Sie müssen den Wert in den neu zugewiesenen Speicher kopieren.

Sie können die printf s in Ihrem Code nicht sehen, da die Ausgabe gepuffert wird und Ihr Code abstürzt, bevor der Puffer geleert wird. Wenn Sie exit(0) direkt nach Ihrem printf("error"); Sie werden sehen, dass es funktioniert.





segmentation-fault