Search code examples
c++graphmemory-leaksshared-ptrdigraphs

Unhlandled exception due to bad pointer usage


it's my first question here so I apologize for eventual formal mistakes you may found in my post.

I'm coding a simple class for "Undirected Connected Weighted Graphs", which must use Adjacency Lists based on vectors.

The issue is that when I run the program from Eclipse, MS Windows says it "stops working" and after debugging I get an "Unhandled exception at 0x00AE251A .... Access violation writing location..." message. Looking around I found that this issue may be caused by a missing pointer destruction or pointer initialization (?). I switched from the standard pointer to the shared_ptr to troubleshoot this issue but the error is the same...

Can anybody enlighten me on this? I lost almost a whole day trying to find the cause without success.

class UndirectedGraph
{
private:
    int V;                                  
    std::vector<std::shared_ptr<std::pair<int,int>>>* adj;    
public:
    UndirectedGraph(int V)
{
        this->V = V;
        this->adj = new std::vector<std::shared_ptr<std::pair<int,int>>>;
}

void addEdge(int v, int w, int weight)
{
    auto sp = std::make_shared<std::pair<int,int>>(std::make_pair(v,weight));
    adj[v].push_back(sp);
}

int main()
{
    UndirectedGraph G1(7);//Ok
    G1.addEdge(0,1,9);//Ok
    G1.addEdge(1,2,5);//Ok
    G1.addEdge(2,0,8);//EXCEPTION RAISED HERE (if line is commented all run fine)
    return 0;
}

Solution

  • I noticed a couple of errors in the code:

    1. If what you need are adjacency lists, then this->adj should be a vector of vectors. Currently, its just a 1-D vector of <int,int> pairs. Instead it should be:

      std::vector<std::vector<std::shared_ptr<std::pair<int,int>>>>* adj;

    2. In the constructor, this->adj should be initialized as follows:

      this->adj = new std::vector<std::vector<std::shared_ptr<std::pair<int,int>>>>(V);

    3. Now, in the addEdge function, you need to first access the vector corresponding to node 'v' and then, into that vector, you need to push the pair (w, weight) [NOTE that, even if we ignore the error that there's only vector, the logic is still incorrect since you're pushing (v, weight) instead of (w, weight) into that vector]. The modified addEdge function would be something like this:

      void addEdge(int v, int w, int weight)
      {
          auto adjacencyList = adj->at(v);
          auto sp = std::make_shared<std::pair<int,int>>(std::make_pair(w,weight));
          adjacencyList.push_back(sp);
      }
      

    Hope this helps you