0

I want to define an array of vectors in c++. Normally I can do it like this:

vector <pair<int,int> > G[100];

I have a function that read data from a file.

My first problem is that I want to define G with size V that read from a file and G should define in main but calling a function with an uninitialized pointer can't work.

My Second problem is when I define G like this:

vector <pair<int, int> > *G;
G = new vector <pair<int, int>>[10];  

it doesn't read data correctly (it doesn't work correctly).

Here is my code:

void readData(vector <pair<int, int> > *G)
{
    int V, E;
    ifstream file("input.txt");
    file >> V >> E;
    //G = new vector <pair<int, int>>[V]; //my problem
    for (int i = 0; i < E; i++)
    { 
        int u, v, w;
        file >> u >> v >> w; 
        G[u - 1].push_back(make_pair(v - 1, w)); 
        G[v - 1].push_back(make_pair(u - 1, w)); 
    }
    file.close();
}
int main() {
    vector <pair<int, int> > *G;
    G = new vector <pair<int, int>>[10]; // my problem
    MST = new vector <pair<int, int>>;
    readData(G);
}

Example data:

5 6
1 3 4
1 2 3
2 4 6
4 3 5
4 5 20
5 2 21

and this code is working correctly and read data from console:

const int N=10;
vector <pair<int,int> > G[N];
int main() {    
    cin >> V>>E;
    for(int i=0; i<E; i++){
        int u,v,w;
        cin >>u>>v>>w; 
        G[u-1].push_back(make_pair(v-1,w)); 
        G[v-1].push_back(make_pair(u-1,w)); 
    }
}
6
  • 1
    One or two things: * Don't accept the Vector as pointer, but instead use a reference. * Why should one create an array of vecs? Could you give please the usecase for this? Use a hashmap if you want a key-value relationship, or a std::array for a fixed array. Commented Oct 15, 2018 at 12:28
  • 4
    Why do you a raw array of vectors? Use a vector of vectors instead. Commented Oct 15, 2018 at 12:28
  • 1
    Use std::vector<std::vector<std::pair<int,int>>> G;. Commented Oct 15, 2018 at 12:40
  • @Galik @Jobberwoky Yes, I can use a vector of vectors. But it doesn't my problem. If I change an array of vectors to a vector of vectors I should edit some functions that use G. Commented Oct 15, 2018 at 12:46
  • 2
    @KarimPazoki Just pass those functions G.data() to pass the internal array that the vector manages. Commented Oct 15, 2018 at 12:47

5 Answers 5

2

There is no reason to use a builtin array when using a vector does exactly what you want. For example you could do this:

void readData(std::vector<std::vector<std::pair<int, int>>>& G)
{
    std::size_t V, E;
    std::ifstream file("input.txt");
    file >> V >> E;
    //G = new vector <pair<int, int>>[V]; //my problem
    G.resize(V); // solved!!!
    for (std::size_t i = 0; i < E; i++)
    {
        std::size_t u, v, w;
        file >> u >> v >> w;
        G[u - 1].push_back(std::make_pair(v - 1, w));
        G[v - 1].push_back(std::make_pair(u - 1, w));
    }
    file.close();
}
int main() {
    std::vector<std::vector<std::pair<int, int>>> G;
//    G = new vector <pair<int, int>>[10]; // my problem
//    MST = new vector <pair<int, int>>;
    readData(G);
}
Sign up to request clarification or add additional context in comments.

Comments

1

You probably should use a vector or vectors instead of a raw array of vectors.

Example:

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

void readData(vector<vector <pair<int, int>>> & G)
{
  int V, E;
  ifstream file("input.txt");

  file >> V >> E;
  G.resize(V);

  for (int i = 0; i < E; i++)
  {
    int u, v, w;
    file >> u >> v >> w;
    G[u - 1].push_back(make_pair(v - 1, w));
    G[v - 1].push_back(make_pair(u - 1, w));
  }
  file.close();
}

int main() {
  vector<vector <pair<int, int>>> G;
  readData(G);

  for (auto & v1 : G)
  {
    for (auto & p : v1)
    {
      cout << p.first << ", " << p.second << "\n";
    }

    cout << "\n";
  }
}

Output:

2, 4
1, 3

0, 3
3, 6
4, 21

0, 4
3, 5

1, 6
2, 5
4, 20

3, 20
1, 21

Hints:

  • don't use all capital variable names, and use meaningful variable names, e.g: data instead of G, nbvectors instead of V and nblines instead of E etc.
  • using namespace std; is not very good practice, but I didn't change the OP's code too much.

Comments

0

My first problem is that I want to define G with size V that read from a file and G should define in main but calling a function with an uninitialized pointer can't work.

You don't need to define the size of G. It's possible to simply declare the vector and add your pairs using the push_back function, as in the code below.

vector <pair<int, int>> G;
while (readFile) {
    G.push_back(make_pair(item1, item2));
}

2 Comments

G is an array of vectors. this answer is not correct. please read end of question and this code is working correctly and read data from console:
@lago Carvalho add includes. #include <iostream> #include <vector> #include<fstream> using namespace std;
0

My first problem is that I want to define G with size V that read from a file and G should define in main but calling a function with an uninitialized pointer can't work.

Quick and dirty fix: Pass a reference to the pointer:

void readData(vector <pair<int, int> >*& G)

Then your main can do this:

vector<pair<int, int>>* MST;
readData(MST);

Then readData cand (and will) change the pointer value (because you passed it by reference).

The better way: Don't use bare C-arrays. Use a vector.

void readData(vector<vector<pair<int, int>>>& G)
{
    size_t V, E;
    ifstream file("input.txt");
    file >> V >> E;
    G.resize(V);

    // Your code...
}

main()
{
    vector<vector<pair<int, int>>> MST;
    readData(MST);
}

//G = new vector <pair<int, int>>[V]; //my problem

That's not the real problem. The problem is that your function takes a vector <pair<int, int> > *G and you overwrite that pointer value it in the above line. The same would happen if your function would take an int and you would just overwrite it: In either case, the caller of the function does not see the change.

void foo(int x) {
  x = 10; // Caller will not see this change.
}

The fix is the same as above: Pass a reference instead.

Comments

-1

You can rewrite your function to return the vector instead:

vector <pair<int, int> >* readData()
{
    int V, E;
    ifstream file("input.txt");
    file >> V >> E;
    vector <pair<int, int> > *G = new vector <pair<int, int>>[V];
    for (int i = 0; i < E; i++)
    { 
        int u, v, w;
        file >> u >> v >> w; 
        G[u - 1].push_back(make_pair(v - 1, w)); 
        G[v - 1].push_back(make_pair(u - 1, w)); 
    }
    file.close();
    return G;
}
int main() {
    MST = new vector <pair<int, int>>;
    vector <pair<int, int> > *G = readGraph();
}

4 Comments

I don't know why. But it doesn't work correctly. I want to have an array like this: 0->|< 2,4>,<1,3>| 1->|<0,3>,<3,6>,<4,21>| ....
In modern c++, scenarios where using new for dynamic allocation is the right solution are very rare. This is not one of them. Just about any time you feel tempted you write new T[x] you can substitute it with a std::vector<T>.
I've retracted my down vote, since this is what OP is actually looking for. But I can't upvote an answer that provides bad advice. Pointing out the problems with the solution or providing a good alternative would complete this answer.
I'm not going to teach the OP the whole C++ at once. Let him first learn to return values from functions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.