简体   繁体   English

使用指向结构的双指针和结构指针重新分配动态二维数组

[英]Reallocation of dynamic 2 dimensional array with double Pointers to structs and struct Pointer

I asked a question aboult allocation and reallocation of a dynamic Pointer within a struct.我问了一个关于结构中动态指针的分配和重新分配的问题。 But now I have within a struct a doublepointer component.但是现在我在一个结构体中有一个双指针组件。

I want to reallocate the adjacency Matrix of a graph after adding vertices.我想在添加顶点后重新分配图的邻接矩阵。

The reallocation of the doublepointer works, but when I want to reallocate the pointers (which the doublepointer is pointing to) in a loop, the programm stops in the first loop run with a segmentation fault...双指针的重新分配有效,但是当我想在循环中重新分配指针(双指针指向的指针)时,程序在第一个循环运行中停止并出现分段错误...

This is my idea (drawn in paint...) myIdea这是我的想法(用油漆绘制...) myIdea

For better readability I divided my code为了更好的可读性,我划分了我的代码

Here is the code Part 1:这是代码第 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;
};

Part 2 with the reallocation problem in updateAdjMat ():第 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;
    }

}

Part 3 with working code:第 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);
}

In my Main I just have a menu to add new vertices with a name and x, y coordinates by calling addVertex在我的 Main 中,我只有一个菜单,可以通过调用 addVertex 添加带有名称和 x、y 坐标的新顶点

Your graph initialization is wrong.您的图形初始化错误。

Firstly, you are passing in a Graph ** so that you can assign a value of Graph * to it.首先,您传入一个 Graph ** 以便您可以为其分配一个 Graph * 值。 But then inside you are allocated a Graph **, not a Graph *.但是在里面你被分配了一个 Graph **,而不是一个 Graph *。 It just so happens that pointers are generally the same size, so it will turn out OK, but the code is wrong.碰巧的是,指针的大小通常相同,所以结果是可以的,但是代码是错误的。

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

You actually want to be allocating a Graph *.您实际上想要分配一个 Graph *。

Even then, afterwards, you have not allocated a Graph.即便如此,之后,您还没有分配 Graph。 All you have allocated is a pointer!你所分配的只是一个指针!

So here you have code that is following two pointers, first with *graph and then with ->所以这里你有遵循两个指针的代码,首先是 *graph ,然后是 ->

(*graph)->VertexCounter = 0;

This would normally give you access to the Graph, but you have not allocated a Graph, you have only allocate a pointer to a graph.这通常会让您访问 Graph,但您尚未分配 Graph,您只分配了一个指向图的指针。 So this could very well crash at this point.所以这很可能在这一点上崩溃。 Anything that follows might crash.接下来的任何事情都可能会崩溃。

I found the solution.我找到了解决方案。 The problem was, that the memory I wanted to reallocate in the for loop wasn't initialized.问题是,我想在 for 循环中重新分配的内存没有初始化。

With that for loop it started to work:有了这个 for 循环,它开始工作:

    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
            }

        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM