Royston
Royston

Reputation: 13

Segmentation fault with vector of vectors

I get segmentation fault when I run the following code.

Given a list of people each with some set of integers, the program has to find the number of friends of the first person where a person is a friend of another person if the number of integers one has in common with the other is greater than a given threshold value K

#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

class B {
public:
  vector<int> b;
  B() { b.reserve(301); }
};

int count(vector<int> u, vector<int> v) // To count the number of integers one
                                        // vector has with the other
{
  sort(u.begin(), u.end());
  sort(v.begin(), v.end());

  int i = 0, j = 0, ctr = 0;

  while (i < u.size() && j < v.size())
    if (u[i] == v[j])
      ctr++;
    else if (u[i] > v[j])
      j++;
    else
      i++;

  return ctr;
}

int main() {

  B null;
  int n, k, p, temp,
      ctr = 0; // n is number of people and k is the threshold value
  cin >> n >> k;

  vector<B> id;
  id.resize(n);

  bool isfriend[n];

  for (int i = 0; i < n; i++) {
    cin >> p; // p is the number of integers for the person i
    for (int j = 0; j < p; j++) {
      cin >> temp;
      id[i].b.push_back(
          temp); // If this line is removed, there is no segmentation fault
    }
  }

  for (int i = 0; i < n; i++)
    isfriend[i] = false;

  isfriend[0] = true;

  queue<int> q;
  q.push(0);

  while (q.empty() == false) {
    p = q.front();
    q.pop();

    for (int i = 0; i < n; i++)
      if (isfriend[i] == false) {
        temp = count(id[p].b, id[i].b);
        if (temp >= k) {
          ctr++;
          q.push(i);
          isfriend[i] = true;
        }
      }
  }

  cout << ctr; // No. of friends of person 0

  return 0;
}

Can anyone tell me where I have gone wrong?

Upvotes: 1

Views: 118

Answers (1)

Christophe
Christophe

Reputation: 73366

Your counting logic is flawed. This leads to an endless loop. I guess you see a segmentation fault because you're in an online Hackerrank-like system that interrupts your code:

The problem is here:

while(i<u.size()&&j<v.size())
    if(u[i]==v[j])
        ctr++;     // <======= once there is a match i, and j never get updated
    else if(u[i]>v[j])
        j++;
    else
        i++;

Correction:

while(i<u.size()&&j<v.size())
    if(u[i]==v[j]) {
        ctr++;     
        i++; j++; // <--- skip the matching elements
    }
    else if(u[i]>v[j])
        j++;
    else
        i++;

The problem disapeared when you removed the push_back() as explained in your comments, because the comparison loop would end immediately.

Not related:

  • consider avoiding variable length arrays, since these are not standard C++. So instead of bool isfriend[n]; prefer vector<bool> isfriend(n, false); which has the advantage of avoiding you having to write a for-loop just to initialize the values.

  • avoid naming variables null. This is confusing. So delete the statement B null; which is not needed anyway.

  • Online demo with your code corrected and these suggestions and a small test sample.

Upvotes: 2

Related Questions