Using std:: vector with MPI_Gather crashes while c-style array works fine

Viewed 78

I'm practising this code and it works with a C-style array but is not working with std::vector. I do not know the problem but it seems it cannot terminate the process. Does anyone know what's wrong with this implementation?

#include <fstream>
#include <iostream>
#include <vector>
#include "mpi.h"
using namespace std;
const int N = 3;
    
int main()
{
    MPI_Init(NULL, NULL);
    int rank;
    int size;
    int root = 0; 
    vector<int> x(N);
    //int x[N]; 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
        
    //int leng = size * N; 
    const int leng = 4 * N; 
    vector<int> single_arr(leng);
    //int single_arr[leng];
    
    for (int i = 0; i < N;i++) {
        x[i] = rank + i; 
        cout << x[i] << endl; 
    }
    
    MPI_Gather(&x, N, MPI_INT, &single_arr, N, MPI_INT, root, MPI_COMM_WORLD);
    MPI_Finalize();
}
1 Answers

You cannot just use the address of a std::vector where a C-style array is expected as an argument. Instead, use the data() member function:

    MPI_Gather(x.data(), N, MPI_INT, &single_arr, N, MPI_INT, root, MPI_COMM_WORLD);

Alternatively (especially if you are using a pre-C++11 compiler), you can pass the address of the vector's first element:

    MPI_Gather(&x[0], N, MPI_INT, &single_arr, N, MPI_INT, root, MPI_COMM_WORLD);

As the elements comprising any std::vector are guaranteed to be contiguous, the address of its first element will be sufficient for a function that expects a (similarly contiguous) 'old-style' array. But note that neither of the above two methods will work if the vector is empty.

Related