简体   繁体   English

如何在 C++ 中返回结构数组

[英]How to return structure array in C++

So I've been trying to implement Kruskal's algorithm, first I want to make clear the question is not related to the implementation of the algorithm.所以我一直在尝试实现Kruskal的算法,首先我想明确这个问题与算法的实现无关。 I've created one graph.hpp file, one kruskalsAlgo.hpp and main.cpp as follows respectively:我创建了一个graph.hpp文件,一个kruskalsAlgo.hppmain.cpp ,分别如下:

#pragma once

struct Edge
{
    int source;
    int destination;
    int weight;
};

struct Graph
{
    int V;
    int E;

    Edge* edge;
};

Graph* create_graph(int V, int E)
{
    Graph* graph = new Graph;
    graph -> V = V;
    graph -> E = E;

    graph -> edge = new Edge[E];

    return graph;
}
#include <stdlib.h>
#include <tuple>

#include "../Graph/Graph.hpp"

class Kruskals_Algo
{
    private:
        struct subset
        {
            int parent;
            int rank;
        };

        void make_set(subset*, int);
        int find_set(subset*, int);
        void _union(subset*, int, int);
    
    public:
        Edge* kruskal(Graph*);
        void print_kruskals_MST(Edge*, int);
};

void Kruskals_Algo::make_set(subset* subsets, int V)
{
    subsets[V].parent = V;
    subsets[V].rank = 0;
}

int Kruskals_Algo::find_set(subset* subsets, int V)
{
    if(subsets[V].parent != V)
        subsets[V].parent = find_set(subsets, subsets[V].parent);
    
    return subsets[V].parent;
}

void Kruskals_Algo::_union(subset* subsets, int x, int y)
{
    int xroot = find_set(subsets, x);
    int yroot = find_set(subsets, y);

    if(subsets[xroot].rank < subsets[yroot].rank)
        subsets[xroot].parent = yroot;
    
    else if(subsets[xroot].rank > subsets[yroot].rank)
        subsets[yroot].parent = xroot;

    else
    {
        subsets[yroot].parent = xroot;
        subsets[xroot].rank++;
    }
}

inline int myComp(const void* a, const void* b)
{
    Edge* a1 = (Edge*)a;
    Edge* b1 = (Edge*)b;
    return a1 -> weight > b1 -> weight;
}

Edge* Kruskals_Algo::kruskal(Graph* graph)
{
    int V = graph -> V;
    Edge result[V];
    Edge* result_ptr = result;
    int e = 0;
    int i = 0;

    qsort(graph -> edge, graph -> E, sizeof(graph -> edge[0]), myComp);

    subset* subsets = new subset[(V * sizeof(subset))];

    for (int v = 0; v < V; ++v)
        make_set(subsets, v);

    while(e < V - 1 && i < graph -> E)
    {
        Edge next_edge = graph -> edge[i++];

        int x = find_set(subsets, next_edge.source);
        int y = find_set(subsets, next_edge.destination);

        if (x != y)
        {
            result[e++] = next_edge;
            _union(subsets, x, y);
        }
    }
    //return std::make_tuple(res, e);
    return result_ptr;
}

void Kruskals_Algo::print_kruskals_MST(Edge* r, int e)
{
    int minimumCost = 0;
    for(int i=0; i<e; ++i)
    {
        std::cout << r[i].source << " -- "
                  << r[i].destination << " == "
                  << r[i].weight << std::endl;
        minimumCost = minimumCost + r[i].weight;
    }
    
    std::cout << "Minimum Cost Spanning Tree: " << minimumCost << std::endl;
}
#include <iostream>

#include "Graph/Graph.hpp"

#include "Kruskals_Algo/kruskalsAlgo.hpp"
//#include "Prims_Algo/primsAlgo.hpp"

using namespace std;

class GreedyAlgos
{        
    public:
        void kruskals_mst();
        //void prims_mst();
};

void GreedyAlgos::kruskals_mst()
{
    Kruskals_Algo kr;
    int V;
    int E;
    int source, destination, weight;
    
    cout << "\nEnter the number of vertices: ";
    cin >> V;
    cout << "\nEnter the number of edges: ";
    cin >> E;
    
    Edge* res;

    Graph* graph = create_graph(V, E);

    for(int i=0; i<E; i++)
    {
        cout << "\nEnter source, destinstion and weight: ";
        cin >> source >> destination >> weight;
        graph -> edge[i].source = source;
        graph -> edge[i].destination = destination;
        graph -> edge[i].weight = weight;
    }

    //std::tie(result, E) = kr.kruskal(graph);
    res = kr.kruskal(graph);
    kr.print_kruskals_MST(res, E);
}

int main()
{
    int choice;
    GreedyAlgos greedy;
    greedy.kruskals_mst();
    
    return 0;
}

So my question here is when I debug the program the values in Edge result[V] , which is a structure array, are calculated correctly, at position [0] [1] [2] as in the following picture:所以我的问题是,当我调试程序时,结构数组Edge result[V]中的值在 position [0] [1] [2]处被正确计算,如下图所示:

在此处输入图像描述

but when the function print_kruskals_MST(res, E) is called from the main the values printed are different:但是当从主调用 function print_kruskals_MST(res, E)时,打印的值是不同的:

在此处输入图像描述

Is there any pointer thing that I'm doing wrong?我做错了什么指针的事情吗? Thanks in advance.提前致谢。 PS Ignore the comments! PS忽略评论!

This answer might not answer your question directly but it should shed some light on the problem.这个答案可能不会直接回答你的问题,但它应该对这个问题有所了解。

First of all, yes you have a lot of pointer problems...首先,是的,你有很多指针问题......

Secondly, pair ANY use of the new operator with the delete operator.其次,将new运算符的任何使用与delete运算符配对。 As it stands, you have a bunch of memory leaks.就目前而言,您有一堆 memory 泄漏。

Also, why create_graph ?另外,为什么create_graph Create a constructor for Graph instead (and a destructor since the class has an Edge* edge it needs to take care of).而是为Graph创建一个构造函数(以及一个析构函数,因为 class 有一个需要处理的Edge* edge )。

struct Graph
{
    int V;
    int E;

    Edge* edge;

    // constructor
    Graph(int V, int E)
    {
        this->V = V;
        this->E = E;
        this->edge = new Edge[E];
    }

    // destructor
    ~Graph()
    {
        // nullify the member variable before deleting its memory is just a safety measure pertaining to multithreading.
        Edge* _edge = this->edge;
        this->edge = nullptr;
        delete _edge;
    }
};

Then change Graph* graph = create_graph(V, E);然后改变Graph* graph = create_graph(V, E); into Graph* graph = new Graph(V, E);进入Graph* graph = new Graph(V, E); and do delete graph when you're done using it.并在使用完毕后delete graph

Make sure you remove all memory leaks and we can go on to discussing referencing the correct data (f.ex. by me changing my answer).确保删除所有 memory 泄漏,我们可以 go 继续讨论引用正确的数据(例如,通过我更改我的答案)。

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

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