Перераспределение динамического c 2-мерного массива с двойными указателями на структуры и структуры указателя - PullRequest
0 голосов
/ 20 января 2020

Я задал вопрос о распределении и перераспределении динамического c Указателя внутри структуры. Но теперь у меня внутри структуры компонент с двойной точкой.

Я хочу перераспределить матрицу смежности графа после добавления вершин.

Перераспределение двойной точки работает, но когда я хочу перераспределить указатели (на которые указывает двойной указатель) в al oop, программа останавливается при первом запуске l oop с ошибкой сегментации ...

Это моя идея (нарисованная в краске .. .) myIdea

Для лучшей читаемости я разделил мой код

Вот код Часть 1:

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

struct Vertices
{
    int id;
    char name[15];
    float xPos;
    float yPos;
};

struct Edge
{
    int id;
    struct Vertices *start;
    struct Vertices *end;
};


struct Graph
{
    int VertexCounter;
    struct Vertices *vertex;
    struct Edge **adjMat;
};

Часть 2 с проблемой перераспределения в updateAdjMat ():

//Initializing graph
void initGraph(struct Graph **graph)
{
    *graph = calloc (1, sizeof(struct Graph **));
    if (!*graph) {
        perror ("calloc-*graph");
        exit (EXIT_FAILURE);
    }

    (*graph)->vertex = NULL;
    (*graph)->adjMat = NULL;
    /*
    (*graph)->adjMat = calloc (1, sizeof (struct Edge **));
    if (!(*graph)->adjMat) {
        perror ("calloc-(*graph)->adjMat");
        exit (EXIT_FAILURE);
    }
    */

    (*graph)->VertexCounter = 0;
}


void updateAdjMat (struct Graph *graph)
{
    int i;

    void *tmp = realloc (graph->adjMat, graph->VertexCounter * sizeof (struct Edge *));
    if (!tmp) 
    {
        perror ("realloc-graph->adjMat");
        exit (EXIT_FAILURE);
    }

    graph->adjMat = tmp;

    for (i = 0; i < graph->VertexCounter; i++)
    {
        void *tmp = realloc (*(graph->adjMat + i), (graph->VertexCounter) * sizeof (struct Edge));
        if(!tmp)
        {
            perror ("realloc-*(graph->adjMat + i)");
            exit (EXIT_FAILURE);
        }
        *(graph->adjMat + i) = tmp;
    }

}

Часть 3 с рабочим кодом:

//reallocating the memory for the vertex pointer
void addVertex (struct Graph *graph, char name[15], float x, float y)
{
    void *tmp = realloc (graph->vertex, (graph->VertexCounter + 1) * sizeof(*graph->vertex));
    if (!tmp) {
        perror ("realloc-(*graph)->vertex");
        exit (EXIT_FAILURE);
    }
    graph->vertex = tmp;

    (graph->vertex + graph->VertexCounter)->id = graph->VertexCounter + 1;
    strcpy((graph->vertex + graph->VertexCounter)->name, name);
    (graph->vertex + graph->VertexCounter)->xPos = x;
    (graph->vertex + graph->VertexCounter)->yPos = y;

    graph->VertexCounter++;

    updateAdjMat(graph);
}

void menu_addVertex (struct Graph *graph)
{
    char name[15];
    float xPos, yPos;

    printf ("\nWhats the name of the vertex?\n");
    scanf ("%s", &name);
    printf ("\nX Coordinate?\n");
    scanf ("%f", &xPos);
    printf ("\nY Coordinate?\n");
    scanf ("%f", &yPos);
    printf ("\n");

    addVertex (graph, name, xPos, yPos);
}

//free the allocated memory
void freeGraph (struct Graph *graph)
{
    free (*(graph->adjMat));
    free (graph->adjMat);
    free (graph->vertex);
    free (graph);
}

В моем главном меню у меня просто есть меню для добавления новых вершин с именем и координатами x, y по вызов addVertex

Ответы [ 2 ]

0 голосов
/ 21 января 2020

Я нашел решение. Проблема заключалась в том, что память, которую я хотел перераспределить в для l oop, не была инициализирована.

С этим для l oop она начала работать:

    for (i = 0; i < graph->VertexCounter; i++)
    {
        //if the new column wasn't initialized
        if (i + 1 == graph->VertexCounter) {
            *(graph->adjMat + i) = calloc(graph->VertexCounter, sizeof **graph->adjMat);
        }
        else {
            void *tmp = realloc (*(graph->adjMat + i), graph->VertexCounter * sizeof (**graph->adjMat));
            if(!tmp)
            {
                perror ("realloc-*(graph->adjMat + i)");
                exit (EXIT_FAILURE);
            }
            *(graph->adjMat + i) = tmp;
        }

        for (j = 0; j < graph->VertexCounter; j++)
        {
            if (i + 1 == graph->VertexCounter || j + 1 == graph->VertexCounter)
            {
                //Doing some initialization to the new edges
            }

        }
    }
0 голосов
/ 20 января 2020

Ваша инициализация графа неверна.

Во-первых, вы передаете график **, чтобы вы могли присвоить ему значение Graph *. Но тогда внутри вас выделяется График **, а не График *. Просто так получилось, что указатели, как правило, имеют одинаковый размер, поэтому все будет хорошо, но код неправильный.

*graph = calloc (1, sizeof(struct Graph **));

Вы действительно хотите выделить Graph *.

Даже тогда, впоследствии, вы не разместили График. Все, что вы выделили, это указатель!

Итак, здесь у вас есть код, который следует за двумя указателями, сначала с * graph, а затем с ->

(*graph)->VertexCounter = 0;

Это обычно дает вам доступ к График, но вы не разместили График, у вас есть только указатель на график. Так что это может очень хорошо сделать sh на данный момент. Все, что следует, может взломать sh.

...