4

I'm trying to figure out how to pass 2D array, which is constructed dynamically to a function. I know that number of columns must be specified, but it my case it depends on user input.

Are there any workarounds?

Example:

// Some function
void function(matrix[i][j]) {
// do stuff
}
// Main function
int N;
cout << "Size: ";
cin >> N;

int matrix[N][N];

for (int i=0;i<N;i++) { // 
 for (int j=0;j<N;j++) { 
  cin >> matrix[N][N];
 }
}

sort(matrix);

You get the idea :)

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
c4rrt3r
  • 612
  • 2
  • 7
  • 18
  • Been discussed before. From http://stackoverflow.com/search?q=c%2B%2B+multidimensional+array I find [How to pass a multidimensional array to a function in C and C++](http://stackoverflow.com/questions/2828648/how-to-pass-a-multidimensional-array-to-a-function-in-c-and-c) and many others. You can also do the search with c and get some more answers that are correct but not necessarily idomatic. – dmckee --- ex-moderator kitten Dec 13 '10 at 23:26
  • @Kos: you need more rep to see the deleted answer that's included in UncleBen's count. – Ben Voigt Dec 13 '10 at 23:45
  • @dmckee: Noticed the variable-length automatic array AFTER answering... which makes my answer less than helpful and also makes this not a duplicate of the question you found. Probably is a duplicate of some other question, though. – Ben Voigt Dec 13 '10 at 23:55
  • @Ben: Uh...yeah. I think you are right. ::sigh:: Remind me, if I every teach c or c++, to spend a while on this problem: really understanding it will set the students right on several subtle points. – dmckee --- ex-moderator kitten Dec 14 '10 at 00:02
  • @Ben - btw, actually, you can :) That's legal in C99, and also possible in most C++ compilers today... Not sure about how C++ standards relate to that. – Kos Dec 14 '10 at 00:12
  • @Kos -- thanks for the correction, I'll remove my uninformed comment – Ben Voigt Dec 14 '10 at 00:17
  • I googled to confirm whether I remember correctly the C99 part and I've found something even more interesting - see my revised post :) – Kos Dec 14 '10 at 00:25
  • @Kos: google works... or you could've just read my updated answer, might've saved you 12 minutes searching – Ben Voigt Dec 14 '10 at 01:04

9 Answers9

4

If you're on C++, the reasonable options are to:

  • use boost::multi_array (recommended), or
  • make your own 2D array class. Well, you don't have to, but encapsulating 2D array logic in a class is useful and makes the code clean.

Manual 2D array indexing would look like this:

void func(int* arrayData, int arrayWidth) {
    // element (x,y) is under arrayData[x + y*arrayWidth]
}

But seriously, either wrap this with a class or enjoy that Boost already has that class ready for you. Indexing this manually is tiresome and makes the code more unclean and error-prone.


edit

http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html says that C99 has one more solution for you:

void func(int len, int array[len][len]) {
   // notice how the first parameter is used in the definition of second parameter
}

Should also work in C++ compilers, but I haven't ever used this approach.

Kos
  • 70,399
  • 25
  • 169
  • 233
  • I think I'm not able to use any library or class. Need to use manual method. Still getting error: "cannot convert `int ()[((unsigned int)((int)N))]' to `int**' for argument `1' to `void func(int*, int)' ". How to pass then? (func(matrix,N);) – c4rrt3r Dec 13 '10 at 23:58
  • 1
    @c4rrt3r: Try `func(&matrix[0][0], N);` – Ben Voigt Dec 14 '10 at 00:11
  • 1
    `func(&matrix[0][0], N)` is OK. (Oops, I'm late :)) – Kos Dec 14 '10 at 00:12
1

In C++, the compiler can figure out the size, since it's part of the type. Won't work with dynamically sized matrices though.

template<size_t N, size_t M>
void function(int (&matrix)[N][M])
{
  // do stuff
}

EDIT: In GCC only, which is required for your code defining the array, you can pass variable-length arrays directly:

void func(int N, int matrix[N][N])
{
  //do stuff
}

See the gcc documentation

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
1
/*******************************************************\
*                                                       *
* I am not claiming to be an expert, but I think I know *
* a solution to this one. Try using a Vector Container  *
* instead of an array. Here is an example below:        *
*                                                       *
* Load the target file with a Multiplication Table      *
*                                                       *
*                                                       *
\*******************************************************/

// reading a text file
#include <iostream>
#include <fstream>
#include <string>
#include <vector>


std::string user_file;
int user_size = 2;
void array_maker(int user_size, std::string user_file);

int main () {
  std::cout << "Enter the name of the file for your data: ";
  std::cin >> user_file;
  std::cout << std::endl;
  std::cout << "Enter the size for your Multiplication Table: ";
  std::cin >> user_size;

  // Create the users Multiplication data
     array_maker(user_size, user_file);

  return (0);
}

void array_maker(int user_size, std::string user_file)
{
  // Open file to write data & add it to end of file
  std::ofstream target_file(user_file,std::ios::out | std::ios::app);

  // Declare the vector to use as a runtime sized array
  std::vector<std::vector<int>> main_array;

  // Initialize the size of the vector array
  main_array.resize(user_size+1); // Outer Dimension
  for (int i=0; i <= user_size; ++i) // Inner Dimension
  {
    main_array[i].resize(user_size+1);
  }

  for (int i=0; i<=user_size; ++i) 
  {
    for (int j=0; j<=user_size; ++j)
    {
      main_array[i][j] = i * j;
      // output line to current record in file
      target_file << i << "*" 
              << j << "=" 
              << main_array[i][j] << " "
              << "EOR"   // End of Record 
              << std::endl;

    } // Close Inner For
  } // Close Outer For
  // close file
  target_file.close();

} // Close array_maker function
Nicole Cook
  • 316
  • 1
  • 5
  • 11
  • 1
    As an aside, a vector of vectors is a horrible way to implement a 2d matrix in performance critical code. Memory reads and cache performance all go to hell. – Ed S. Jun 12 '12 at 21:24
0

to pass multi dimensional arays into method the compiler needs to know the depth of each field, so one solution is to use templates and call method in a normal way and the compiler will guess the size of each field.

template <size_t m>
void method(int M[][m])
{
    for(int i=0; i<m; ++i)
        for(int j=0; j<m; ++j)
        {
            // do funny stuff with M[i][j]
        }
}

int main()
{
    int M[5][5] = { {1,0,1,1,0}, {0,1,1,1,0}, {1,1,1,1,1}, {1,0,1,1,1}, {1,1,1,1,1} };
    method(M);
    // also you can call with method<5>(M)
    // if you have different sizes for each dimension try passing them in args
    return 0;
}
Kelibiano
  • 81
  • 1
0

You can do void function (int** __matrix, int32_t __row, int32_t __column) __row - max rows __column - max columns.

You will need those params to find out the limits of the array.

Rajivji
  • 305
  • 1
  • 2
0

Just add another parametrs to your function - row_number and column_number. Arrays are not object in C++ so they don't store any additional information about themselfs.

IProblemFactory
  • 9,551
  • 8
  • 50
  • 66
0

If you pass in the array identifier (as a pointer to a pointer) you will need to use pointer arithmetic:

void function(int** matrix, int num_rows, int num_cols) {
    Assert(matrix!=NULL && *matrix!=NULL && num_rows>0 && num_cols>0);

    for(int i=0; i<num_rows; i++) {
        for(int j=0; j<num_cols; j++) {
            // cannot index using [] like matrix[i][j]
            // use pointer arithmetic instead like:
            // *(matrix + i*num_cols + j)

        }
    }
}
thejartender
  • 9,339
  • 6
  • 34
  • 51
Sonny Saluja
  • 7,193
  • 2
  • 25
  • 39
-1
int r, c
int *matrix = new int[r,c];
for (int i = 0; i < r; i++)
    {
        /*cout << "Enter data" << endl;*/
        for (int j = 0; j < c; j++)
        {
            cin >> matrix[i,j];

        }
    }
M.Pak
  • 1
  • 1
-3

void function(int &matrix[][] )

newprint
  • 6,936
  • 13
  • 67
  • 109