Reputation: 561
Want to construct a Graph with adjacency list, but getting seg-fault when I add elements to vector<vector<int>>
. adj.size()
prints 5
which tells it has allocated memory, why the seg-fault in addEdge()
method?
#define V 5
struct Edge {
int src, dst;
};
void addEdge(vector<vector<int>> &adj, int u, int v)
{
adj[u].push_back(v);
}
void constructGraph(vector<vector<int>> &adj, vector<Edge> &edges)
{
for(Edge e : edges)
{
addEdge(adj, e.src, e.dst);
}
}
int main()
{
vector<vector<int>> adj(V);
vector<Edge> edges =
{
{ 0, 1 }, { 1, 2 }, { 2, 0 }, { 2, 1 },
{ 3, 2 }, { 4, 5 }, { 5, 4 }
};
constructGraph(adj, edges);
return 0;
}
Upvotes: 0
Views: 249
Reputation: 36597
void addEdge(vector<vector<int>> &adj, int u, int v)
{
adj[u].push_back(v);
}
is incorrect. The operator[]()
for a vector ASSUMES the supplied index is valid. If u
is not valid, the behaviour is undefined.
In your code, the vector passed has five elements, and the last edge in main()
vector<Edge> edges =
{
{ 0, 1 }, { 1, 2 }, { 2, 0 }, { 2, 1 },
{ 3, 2 }, { 4, 5 }, { 5, 4 } // note the last pair here
};
will cause addEdge()
to be called with u
having a value of 5
. That is one past the end.
While #define V 6
will fix the problem, it doesn't protect addEdge()
from being passed a bad value of u
. Instead I would implement addEdge()
so it protects itself from bad data as follows.
void addEdge(vector<vector<int>> &adj, int u, int v)
{
if (u < 0) return; // handle negative u
if (u >= adj.size()) adj.resize(u+1); // resize if needed
adj[u].push_back(v);
}
An even better approach would be to avoid using supplied data - such as the data in edges
in your main()
- as array indices at all.
Upvotes: 3
Reputation: 561
Solved. Thanks for the guidance provided here, read up more on this and learnt that c++ language has protection built into it for these kinds of issues. Using .at() method protects the programmer from out-ob-bounds accesses.
void addEdge(vector<vector<int>> &adj, int u, int v)
{
adj.at(u).push_back(v);
}
if you use adj.at(u) instead of adj[u], program exits little gracefully
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check: __n (which is 5) >= this->size() (which is 5)
Aborted (core dumped)
Upvotes: 0