Segmentation fault when accessing vector from array of vectors [closed]

  arrays, c++, segmentation-fault, vector

Context

I have an object, that I initialize as a nullptr, and I pass it to different functions that modify it.

int main(int argc, char **argv)
{
  Graph *graph = nullptr;
  ...

Down the line, for instance, I call

initialize(&graph, &input);
graph->findShortestPath(from, to);

And this all works as expected. initialize creates the graph, and I can find the shortest path.

The problem

My graph has edges as an array of vectors:

class Graph
{
public:
    ...
    std::vector<int> *edges[];
    ...

Now, I’m passing the graph to a function like the one below:

std::string compute(Graph **graph)

From main:

compute(&graph)

In this function, I can retrieve the vector from the array with

std::vector<int> *e = ((*graph)->edges[0]);

But as soon as I call any methods in the vector, I get Segmentation fault: 11.

For instance, with:

e->capacity();

More context

This is how I initialize my graph:

char initialize(Graph **graph, std::istringstream *input) {

    ...

    int V = (*graph)->total_vertices;
    *(*graph)->edges = new std::vector<int>[V + 1];

    for (unsigned int i = 0; i < pairs.size(); i += 2)
    {
      int from = pairs[i];
      int to = pairs[i + 1];

      if (0 < from && from <= V && 0 < to && to <= V)
      {
        auto e = (*graph)->edges;
        (*e)[from].push_back(to);
        (*e)[to].push_back(from);
      }
      ...

I suspect that the error is in how I initialize the edges, but I don’t know what’s wrong, since the graph methods work.

Edit: Minimal reproducible code:

Here the segmentation fault is in std::cout << e->size() << std::endl;

class G
{
public:
  int total_vertices;
  std::vector<int> *edges[];
  G(int total_vertices);
};

G::G(int total_vertices)
{
  this->total_vertices = total_vertices;
  *edges = new std::vector<int>[total_vertices + 1];
}

void initialize(G **graph, int V)
{
  *graph = new G(5);
  std::vector<int> pairs = {1, 5, 5, 2, 1, 4, 4, 5, 4, 3, 2, 4};

  *(*graph)->edges = new std::vector<int>[V + 1];

  for (unsigned int i = 0; i < pairs.size(); i += 2)
  {
    int from = pairs[i];
    int to = pairs[i + 1];

    if (0 < from && from <= V && 0 < to && to <= V)
    {
      auto e = (*graph)->edges;
      (*e)[from].push_back(to);
      (*e)[to].push_back(from);
    }
  }
}

void compute(G **graph, int V)
{
  for (int i = 1; i < V; i++)
  {
    std::vector<int> *e = (*graph)->edges[i];
    std::cout << e->size() << std::endl;
  }
}

int main(int argc, char **argv)
{
  int V = 5;
  G *graph = nullptr;
  initialize(&graph, V);
  compute(&graph, V);
}

Disclaimer: you can probably tell, but I have almost zero experience with C++, and yes, there’s code smells. So feel free to point them out with suggestions on what to improve.

Source: Windows Questions C++

LEAVE A COMMENT