Passing a 2D array to a C++ function
There are three ways to pass a 2D array to a function:
The parameter is a 2D array
int array[10][10];
void passFunc(int a[][10])
{
// ...
}
passFunc(array);The parameter is an array containing pointers
int *array[10];
for(int i = 0; i < 10; i++)
array[i] = new int[10];
void passFunc(int *a[10]) //Array containing pointers
{
// ...
}
passFunc(array);The parameter is a pointer to a pointer
int **array;
array = new int *[10];
for(int i = 0; i <10; i++)
array[i] = new int[10];
void passFunc(int **a)
{
// ...
}
passFunc(array);
How to pass 2D array (matrix) in a function in C?
C does not really have multi-dimensional arrays, but there are several ways to simulate them. The way to pass such arrays to a function depends on the way used to simulate the multiple dimensions:
1) Use an array of arrays. This can only be used if your array bounds are fully determined at compile time, or if your compiler supports VLA's:
#define ROWS 4
#define COLS 5
void func(int array[ROWS][COLS])
{
int i, j;
for (i=0; i<ROWS; i++)
{
for (j=0; j<COLS; j++)
{
array[i][j] = i*j;
}
}
}
void func_vla(int rows, int cols, int array[rows][cols])
{
int i, j;
for (i=0; i<rows; i++)
{
for (j=0; j<cols; j++)
{
array[i][j] = i*j;
}
}
}
int main()
{
int x[ROWS][COLS];
func(x);
func_vla(ROWS, COLS, x);
}
2) Use a (dynamically allocated) array of pointers to (dynamically allocated) arrays. This is used mostly when the array bounds are not known until runtime.
void func(int** array, int rows, int cols)
{
int i, j;
for (i=0; i<rows; i++)
{
for (j=0; j<cols; j++)
{
array[i][j] = i*j;
}
}
}
int main()
{
int rows, cols, i;
int **x;
/* obtain values for rows & cols */
/* allocate the array */
x = malloc(rows * sizeof *x);
for (i=0; i<rows; i++)
{
x[i] = malloc(cols * sizeof *x[i]);
}
/* use the array */
func(x, rows, cols);
/* deallocate the array */
for (i=0; i<rows; i++)
{
free(x[i]);
}
free(x);
}
3) Use a 1-dimensional array and fixup the indices. This can be used with both statically allocated (fixed-size) and dynamically allocated arrays:
void func(int* array, int rows, int cols)
{
int i, j;
for (i=0; i<rows; i++)
{
for (j=0; j<cols; j++)
{
array[i*cols+j]=i*j;
}
}
}
int main()
{
int rows, cols;
int *x;
/* obtain values for rows & cols */
/* allocate the array */
x = malloc(rows * cols * sizeof *x);
/* use the array */
func(x, rows, cols);
/* deallocate the array */
free(x);
}
4) Use a dynamically allocated VLA. One advantage of this over option 2 is that there is a single memory allocation; another is that less memory is needed because the array of pointers is not required.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
extern void func_vla(int rows, int cols, int array[rows][cols]);
extern void get_rows_cols(int *rows, int *cols);
extern void dump_array(const char *tag, int rows, int cols, int array[rows][cols]);
void func_vla(int rows, int cols, int array[rows][cols])
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
array[i][j] = (i + 1) * (j + 1);
}
}
}
int main(void)
{
int rows, cols;
get_rows_cols(&rows, &cols);
int (*array)[cols] = malloc(rows * cols * sizeof(array[0][0]));
/* error check omitted */
func_vla(rows, cols, array);
dump_array("After initialization", rows, cols, array);
free(array);
return 0;
}
void dump_array(const char *tag, int rows, int cols, int array[rows][cols])
{
printf("%s (%dx%d):\n", tag, rows, cols);
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
printf("%4d", array[i][j]);
putchar('\n');
}
}
void get_rows_cols(int *rows, int *cols)
{
srand(time(0)); // Only acceptable because it is called once
*rows = 5 + rand() % 10;
*cols = 3 + rand() % 12;
}
(See srand()
— why call it only once?.)
Use of a function on a 2d array
- The function
int function(int **arr)
does not return anint
so make itvoid
. - When you call it,
a = function(&arr[i][0]);
, you do not usea
after the assignment. I suggest that you removea
from the program completely since it's not used anywhere. - The call to the function,
function(&arr[i][0]);
, should simply befunction(arr);
- The function signature needs to include the extent of all but the outermost dimension:
void function(int arr[][M])
- Inside the function, you use
3
and5
instead ofN
andM
. That accesses the array out of bounds. - In
function
, thei
andj
you declare at the start of the function are unused. Remove them. arr[i][j] = arr[i][j] + 50;
is better written asarr[i][j] += 50;
- When initializing a multidimensional array, use braces to make it simpler to read the code:
int arr[N][M] = {{10, 11, 12, 13}, {14, 15, 16, 17}};
- In
main
you mixint
andsize_t
for the indexing variables. I suggest you settle for one type. - Remove unused header files (
string.h
)
Example:
#include <stdio.h>
#define N 2
#define M 4
void function(int arr[][M]) {
for(int i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
arr[i][j] += 50;
}
}
}
int main() {
int arr[N][M] = {{10, 11, 12, 13}, {14, 15, 16, 17}};
for(size_t i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
printf("value of arr[%zu][%zu] is %d\n", i, j, arr[i][j]);
}
}
printf("\n ***values after modification***\n");
function(arr);
// int array print results
for(size_t i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
printf("value of arr[%zu][%zu] is %d\n", i, j, arr[i][j]);
}
}
}
Since you print the array more than once, you could also add a function to do so to not have to repeat that code in main
:
void print(int arr[][M]) {
for(size_t i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
printf("value of arr[%zu][%zu] is %d\n", i, j, arr[i][j]);
}
}
}
To pass 2D Dimensional array as an argument?
This is how to pass in a 2d array to a function. This is about as simple as I can make it. There's no need to define the type (i.e. don't do data[][]
) when defining the function (I think that's where you were going wrong).
// define 2d array
var data = [[0,1],[1,3],[2,6]];
// define function
function myFunction(foobar){
// ... do something with 2d array "foobar" ...
}
// invoke function, passing in 2d array
myFunction(data);
Example: Try it out using a tool like jsbin!
2D-array as argument to function
You can't write void Foo(int bar[][])
, because bar
decays to a pointer. Imagine following code:
void Foo(int bar[][]) // pseudocode
{
bar++; // compiler can't know by how much increase the pointer
// as it doesn't know size of *bar
}
So, compiler must know size of *bar
, therefore size of rightmost array must be provided.
pass 2d array to a function in c++
Problems in your code:
Problem 1
void input(int matrix[][],int num_h){
is not valid C++. In a multi-dimensional array, all but the first dimension must be constants. A valid declaration would be:
// Define a constant at the start of the file.
const int MATRIX_SIZE 200;
void input(int matrix[][MATRIX_SIZE],int num_h){
Problem 2
int matrix[num_h][num_h];
is not valid C++. VLA are not supported in C++.
Suggested Solution
Use std::vector<std::vector<int>>
to capture the 2D array.
Change
void input(int matrix[][],int num_h){
to
void input(std::vector<std::vector<int>>& matrix){
// You can get the size by calling matrix.size()
// There is no need to pass num_h as an argument.
Change the calling code to:
int main(){
Graph g;
int num_h;
cout<<"Enter the number of houses: ";
cin>>num_h;
// Construct a 2D array of size num_h x num_h using std::vector
std::vector<std::vector<int>> matrix(num_h, std::vector<int>(num_h));
g.input(matrix);
return 0;
}
Passing a 2D array to a function / constructor
2D arrays are stored contigously, so you should probably do something like this example:
#include <iostream>
template<size_t N1, size_t N2>
void output(const float (&elements)[N1][N2])
{
for (size_t i = 0; i < N1; i++)
{
for (size_t j = 0; j < N2; j++)
std::cout << elements[i][j] << ' ';
std::cout << std::endl;
}
}
int main()
{
float elements[3][3] = {
{1,2,3},
{1,2,3},
{1,2,3}
};
output<3, 3>(elements);
}
Note how I've used templates because the array size is static, which is another mistake you did
Edit: I understand what you're trying to do, here's how:
Make the Matrix class a template class taking the template parameters rows and columns, and change the elements
parameter into float elements[rows][columns]
template<size_t rows, size_t columns>
class Matrix
{
private:
MatrixData _matrix = MatrixData();
public:
Matrix(float elements[rows][columns])
{
_matrix.rows = rows;
_matrix.columns = columns;
_matrix.elements = new float[rows * columns];
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++)
_matrix.elements[(i * columns) + j] = elements[i][j];
}
};
Then you have to remove the rows and columns constructor parameters because you already have them as template parameters.
Now the object declaration should look like this:
int main()
{
float Identity[3][3] =
{
{1.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
{0.0, 0.0, 1.0}
};
Matrix<3, 3> identity(Identity);
}
Passing a 2D array as Function Argument
You could do this using templates. In particular, using nontype template parameters as shown below:
#include <iostream>
//make func a function template
template<std::size_t N, std::size_t M>
void func(int (&arr)[N][M])
{
std::cout<<"func called with: "<<N<<" rows and "<<M<<" columns"<<std::endl;
}
int main()
{
int arr2[10][15];
func(arr2);
return 0;
}
In the above example N
and M
are called nontype template parameters.
Using templates we can even make the type of elements in the array arbitrary, as shown below:
//make func a function template
template<typename T, std::size_t N, std::size_t M>
void func(T (&arr)[N][M])
{
std::cout<<"func called with: "<<N<<" rows and "<<M<<" columns"<<std::endl;
}
int main()
{
int arr2[10][15];
func(arr2);
float arr3[3][4];
func(arr3);//this works too
return 0;
}
Related Topics
What Is the Underlying Data Structure of a Stl Set in C++
Lvalue to Rvalue Implicit Conversion
Replacing Ld with Gold - Any Experience
Capturing Perfectly-Forwarded Variable in Lambda
Are C++ Templates Just MACros in Disguise
How to Give Priority to Privileged Thread in Mutex Locking
When Should You Use the "This" Keyword in C++
Using Std::Bind with Member Function, Use Object Pointer or Not for This Argument
Printing Prime Numbers from 1 Through 100
Virtual Destructor and Undefined Behavior
How to Build Cmake Externalproject While Configurating Main One
C++ Expected Constant Expression
Use Channel Hiearchy of Boost.Log for Severity and Sink Filtering
For Nested Templates, When Did '>>' Become Standard C++ (Instead of '> >')