1

I just do my homework using graph data structure and use heap memory and I want to clear that memory. My homework is about teachers want to know. How many vertexes that are even number by using Depth First Search. Why deconstructor run 2 times? It makes this program error because it's already deleted that memory.

#include<iostream>
#include <string.h>
struct graph
{
    int vertex;
    int edges;
    int **martrix;
    void setMartrix(int x,int y)
    {
        vertex=x;
        edges=y;
        martrix=new int*[vertex];
        for(int i=0;i<vertex;i++)
            martrix[i]=new int[edges];
        for(int col=0;col<vertex;col++)
        {
            for(int row=0;row<edges;row++)
                martrix[col][row]=0;
        }
    }
    void add_edge(int edge1,int edge2)
    {
        martrix[edge1][edge2]=1;
        martrix[edge2][edge1]=1;
    }
    void print()
    {
        for(int col=0;col<vertex;col++)
        {
            for(int row=0;row<edges;row++)
                std::cout<<martrix[col][row]<<" ";
            std::cout<<std::endl;                   
        }
    }
    ~graph()
    {
        std::cout<<"delete complete"<<std::endl;
        for(int i=0;i<vertex;i++)
            delete martrix[i];
        delete martrix;
        martrix=nullptr;    
    }
};
void findans(graph g)
{
    int ans=0;
    int visited[g.vertex];
    memset(visited,0,sizeof(visited));
    for(int col=0;col<g.vertex;col++)
    {
        for(int row=0;row<g.edges;row++)
        {
            if(g.martrix[col][row]== 1 && !visited[col])
            {
//              std::cout<<col+1<<" ";
                visited[col]=1;
                ans=((col+1)% 2 == 0)? 
                ++ans:
                ans;
            }
        }
    }
//  std::cout<<std::endl;
    std::cout<<ans<<std::endl;
}
int main()
{
    graph g;
    int v,e;
    std::cin>>v>>e;
    g.setMartrix(v,e);
    for(int i=0;i<v;i++)
    {
        int temp1,temp2;
        std::cin>>temp1>>temp2;
        g.add_edge(temp1-1,temp2-1);
    }
    findans(g);
    return 0;
}

input:

5 7
1 2
1 3
1 5
2 5
2 4
3 5
4 3

output:

2
delete complete //this line I just check by print this line to find an error and founded it delete 2 times.
delete complete
Jacky Teerapat
  • 125
  • 1
  • 10
  • "delete martrix;" is wrong. It should be `delete[] martrix;`. "martrix=nullptr;" is completely *pointless*. Why bother setting a pointer to `nullptr` at the end of a destructor? An instant later the pointer ceases to exist. You are also misspelling "matrix". – Jesper Juhl Dec 07 '19 at 16:00
  • This could be a good opportunity to practice creating a [mcve], which is a useful debugging tool. What code can you strip out of your `main` function without getting rid of the error? After you've done that, remove the functions that are no longer being used. That removes the distractions. What's left? – JaMiT Dec 07 '19 at 16:48

2 Answers2

2

You're passing the object g to the function findans() by value. Therefor a copy of the object is created at the start of the function and destroyed at the end. After that, your original object is destroyed at the end of main.

To add more to this, your object has pointer data members but does not have a user-defined copy-constructor. The problem is, is that the default copy-constructor does a shallow copy (pretty much assigning every member to their corresponding pairs). This way, when your copy is deleted, so is the data that your original object points to. To read more about the importance of such things, please read the following: What is the rule of three?.

Your can fix your problem by passing your object to the function by const reference or const pointer if your function is read-only. Otherwise, see if you want to actually modify the original object and decide if you want to pass by reference, pointer or define a copy-constructor and pass by value.

Community
  • 1
  • 1
Rokas Višinskas
  • 533
  • 4
  • 12
0

You should consider using classes instead of structs if you are not solely working with data.

Regarding your question,

Your function

void findans(graph g)

Takes a graph by value. This makes a new variable of type graph and copies the contents in. When this function ends, the destructor for graph is called. When your main function ends, the destructor for your graph declared in main is called for the copy that was created.

If you don't want to copy the graph by value, change this to use a reference so that a new graph object is not created/copied.

void findans(graph& g)
user2980207
  • 293
  • 1
  • 11