What is the equivalent matrix-like C-array of a nested std::vector (for C and C++ interop)?

267 views Asked by At

What is the equivalent matrix-like C-array of a nested std::vector (for C and C++ interop)?

For example, if one wanted to treat std::vector<std::vector<int>> as some kind of int arr[n][m], where n is the dimension of the outer vector and m of the inner vector, then what structure would one use in C?


This is motivated by wanting to have a similar correspondence between matrices in C and C++ as for vectors in:

https://stackoverflow.com/a/1733150/4959635

2

There are 2 answers

5
Nir Friedman On BEST ANSWER

Based on additional information in the comments, let me suggest you do something like this instead:

class TwoDimVector {
 public:
  TwoDimVector(int num_cols, int num_rows)
      : m_num_cols(num_cols)
      , m_num_rows(num_rows)
      , m_data(m_num_cols * m_num_rows, 0)
  { }

  int & ix(int row, int col) {
     return data[num_cols * row + col];
  }


  const int m_num_rows;
  const int m_num_cols;
 private:
  std::vector<int> m_data;
}

When you do nested vectors, there's a lot of extra work happening. Also, with nested vectors, the data is not contiguous, making it hard to work with any C-apis. Notice with this data structure, the size is fixed at construction time and accessible. This is designed to be row contiguous, so for C interoperability you can access extra raw pointers like so:

TwoDimVector tdv(4,3);
int * raw = &tdv.ix(0,0);
int * raw_second_row = &tdv.ix(1,0);

Just note: if you pass this into a function, be sure to pass by reference:

void do_work(TwoDimVector & tdv) {
  ...
}

If you don't pass by reference, it will copy everything, which is a bunch of (typically unnecessary) work.

0
vlad4378 On

Maybe, this code

  void translate(const vector< vector >& vec){

int m = vec.size(), n = 0;

for (vector<int>& deep : vec) // search maximum size if nested vectors
{
    if (deep.size() > n)
        n = deep.size();
}

int arr[m][n];

m = n = 0;
for (vector<int>& deep : vec){
    for (int& x : deep)
    {
        arr[m][n] = x;
        ++n;
    }

    ++m;
}

// So, I really don't know how you can return this array :( }

You see, it code is BAD, you mustn't do it !!!
If you writing on C++ you should using std::vector - it is easier. C-like arrays is heritage from C, you shouldn't using they