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 :)

8
  • Been discussed before. From stackoverflow.com/search?q=c%2B%2B+multidimensional+array I find 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. Commented Dec 13, 2010 at 23:26
  • @Kos: you need more rep to see the deleted answer that's included in UncleBen's count. Commented Dec 13, 2010 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. Commented Dec 13, 2010 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. Commented Dec 14, 2010 at 0: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. Commented Dec 14, 2010 at 0:12

9 Answers 9

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.

Sign up to request clarification or add additional context in comments.

3 Comments

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: Try func(&matrix[0][0], N);
func(&matrix[0][0], N) is OK. (Oops, I'm late :))
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

Comments

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

1 Comment

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.
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.

Comments

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.

Comments

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)

        }
    }
}

5 Comments

Again, this works for ragged array, but not for int[][] type arrays.
There is no primitive in C/C++ which would prevent you from accessing memory outside the limits of the array. My code will work for 2D arrays.
Nope, it will not, as matrix[i][j] won't get you anything useful if you reinterpret int[x][y] as int**. Google what the [] operator does and check for yourself.
Sanjit: This code will not work for a 2D array. It will only work for an array of pointers to int.
You are right. The only to index to matrix[i][j] would be to use pointer arithmetic.
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;
}

Comments

-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];

        }
    }

Comments

-3

void function(int &matrix[][] )

2 Comments

Won't even compile. :) Only the highest-order dimension can be left as unspecified.
This would not compile. You are declaring an array of references not a reference to the array.

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.