Passing a 2d array to a function in C

In summary: Array(int **array, int m, int n){for(int i=0;i<m;i++)for(int j=0;j<n;j++)printf("%d\n",array[i][j]);}int main(){int i,j,k=0, m=5, n=20;std::deque<int> a(m*sizeof(int));for(i=0;i<m;i++)a.push_
  • #1
31si
21
0
I am currently writing a simulation of the game of life in C. I can create a dynamically sizes 2d array in C. However I then want to pass this array to a function.

I have tried to do this however I cannot pass the array if at least one of the dimension sizes and not defined at compile time.

Does anyone know how to do this?
 
Technology news on Phys.org
  • #2
There is no way in C to pass an array to an function. The normal way would be to pass a pointer to the array and then the size as separate arguements.
 
  • #3
I was aware that I would have to pass a pointer but when I try to do this it message up also.

Picture this. I have a 2d array for arguments sakes let's say 50 x 50. I can pass it as a pointer and I can pass it 2 other arugments which are the dimensions. However when I try to reference the array via the pointer it messes up. And seems to put the elements in a different order.

I know I am most likely pushing it a little here for a noob, but is there any chance that someone would be kind enough to provide me some sample code to do this?
 
  • #4
Try:

Code:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
// Ref : http://www.eskimo.com/~scs/cclass/int/sx9b.html
void printArray(int **array, int m, int n)
{
 for(int i=0;i<m;i++)for(int j=0;j<n;j++)printf("%d\n",array[i][j]);
}
int main()
{
      int i,j,k=0, m=5, n=20;
      int **a=(int **)malloc(m*sizeof(int *));
      for(i=0;i<m;i++)a[i]=(int *)malloc(n*sizeof(int));
      for(i=0;i<m;i++)for(j=0;j<n;j++){k++; a[i][j]=k;}
      //for(i=0;i<m;i++)for(j=0;j<n;j++)printf("%d\n",a[i][j]);
      printArray(a,m,n);
      system("PAUSE");
      return 0;
}
 
  • #5
31si said:
I am currently writing a simulation of the game of life
If this is the actual purpose of your efforts (rather than trying to learn a lesson in low-level C memory management), then you really ought to consider using a different language which makes these sorts of things much easier. (e.g. switch to C++, and make use of the standard containers, probably std::deque)
 
  • #6
Many thanks that last one does appear to have done the job. I will have a go at implementing it into my app and I will report back.

A thousand thanks
 
  • #7
Hurkyl said:
If this is the actual purpose of your efforts (rather than trying to learn a lesson in low-level C memory management), then you really ought to consider using a different language which makes these sorts of things much easier. (e.g. switch to C++, and make use of the standard containers, probably std::deque)

I have thought of this however I do not get along well with OOP. I have to study it at uni and I can see the advantages however I just don't think like it and I find it hard to write. I get along a lot better with function/procedural programming.
 
  • #8
31si said:
I have thought of this however I do not get along well with OOP. I have to study it at uni and I can see the advantages however I just don't think like it and I find it hard to write. I get along a lot better with function/procedural programming.
Who said anything about OOP? I was only talking about data types! And the std::deque<std::deque<int> > type is far easier (and safer!) to use than the int** type for two-dimensional dynamic arrays.
 
  • #9
I apologise, I am unfamiliar with C++. I have taught myself C. And all I get taught at uni is Java which is a beast of a language. And I don't mean 'beast' in a good way.
 
  • #10
For some reason I have had an email saying you have reply and i can read it on my mail but it isn't appear in the forum. Anyway, I have read your code and I can see roughly what it is doing however I am not competant in C++ to be able to fulfil the rest of my goal in C++.

I am currently implementing first suggestion with some success.
 
  • #11
Another quick Q. How would I then free the allocated memory once I have done with it?
 
  • #13
Just checking, with the code that you kindly provided for me in the first place. I should be able to create a rectangular array shouldn't I? (i.e one where the rows are greater than the columns or visa versa)
 
  • #14
Never mind sorted the different dimension problem
 
  • #15
I should be able to create a rectangular array

Yes, you can do better than that.
Following the same procedure, you can make mxn, nxm, mxm arrays, i.e. any shape you want.
Even better than that, you can make jagged arrays where the rows are of different sizes.
Even further, following the same principle, you can make 3+ dimension arrays. Obviously in these cases, you need to nest deeper than the example.
Good luck with your work!
 
  • #16
Might have a go at 3d game of life after I have finished the dynamic 2d version. 3d should be a good task. However trying to work out the rule set and a visualisation method could be somewhat interesting.
 
  • #17
Great!
Let us know from time to time how you're doing.
 
  • #18
Will do, I will most likely end up asking more questions about it anyway.
 
  • #19
Code:
#include<stdio.h>
#include<stdlib.h>


void function(int **x);


main()
{
  int nrows=2,ncolumns=2,i,j;


  //memory allocation for x
  int **x=malloc(nrows*sizeof(int*));
  if(x==NULL)
    {
      printf("out of memory\n");
      return 0;
    }
  for(i=0;i<nrows;i++)
    {
      x[i]=malloc(ncolumns*sizeof(int));
      if(x[i]=NULL)
	{
	  printf("out of memory\n");
	  return 0;
	}
    }


  printf("code passed me");//checking


  //define x
  for(i=0;i<2;i++)	  
    for(j=0;j<2;j++)	    
      x[i][j]=i+j+2;
 




  //call function
  function(x); 

}







//function_definition
function(int &x)

{
  int nrows=2,ncolumns=2,i,j,y[2][2];

		  
  for(i=0;i<2;i++)
    for(j=0;j<2;j++)
      y[i][j]=x[i][j]+1;



  //display y
  for(i=0;i<2;i++)
    for(j=0;j<2;j++)
      printf("%d",y[i][j]);		 
}

segmentation fault comes.. help please
 
  • #20
vineeshvs said:
Code:
      if(x[i]=NULL)
one of the issues with C's syntax (some compilers will optionally generate a warning for this), make that
Code:
      if(x[i]==NULL)

You can also do this with a single allocation:

Code:
// single allocation for x (data starts after array of pointers (x+nrows))

int **x=malloc(nrows*sizeof(int*) + (nrows*ncolumns*sizeof(int));

    if(x==NULL)
    {
      printf("out of memory\n");
      return 0;
    }

    for(i=0;i<nrows;i++)
    {
      x[i]=(int *)((int)(x+nrows) + i*ncolumns*sizeof(int));
    }

// ... rest of code ...

    free(x);
 
Last edited:
  • #21
thanks..it works.
if i am allocating memory for x inside a function where should i use free(x), at the end of function or at the end of main program? if i don't use that, will it reduce memory much for ordinary programs (i have 4GB RAM)??
 
  • #22
Reuse of memory inside a function

Code:
#include<stdio.h>
#include<stdlib.h>




int **transpose(int **x,int m,int n);



main()
{
  int nrows=2,ncolumns=2,i,j,k=0;
  

  //memory allocation for array x
  int **array;
  array = malloc(nrows * sizeof(int *));
  if(array == NULL)
    {
      printf("out of memory\n");
      return 0;
    }

  
  for(i = 0; i < nrows; i++)
    {
      array[i] = malloc(ncolumns * sizeof(int));
      if(array[i] == NULL)
	{
	  printf("out of memory\n");
	  return 0;
	}
    }

 

 


  //define x
  printf("x=\n");
  for(i=0;i<2;i++)
    {
printf("\n");	  
  for(j=0;j<2;j++)	    
    {
      k=k+5;
      array[i][j]=i+j+k;
      printf("%d\t",array[i][j]);
    } 
    }
  printf("\n");






  //memory allocation for x_transpose, (storing the transpose returned by function)

  int **x_transpose;
  x_transpose = malloc(nrows * sizeof(int *));
  if(x_transpose == NULL)
    {
      printf("out of memory\n");
      return 0;
    }

  
  for(i = 0; i < nrows; i++)
    {
      x_transpose[i] = malloc(ncolumns * sizeof(int));
      if(x_transpose[i] == NULL)
	{
	  printf("out of memory\n");
	  return 0;
	}
    }







  //call function
  x_transpose= transpose(array,nrows,ncolumns);






  //display transpose
  printf("x_transpose=\n");
  for(i=0;i<2;i++)
    {
printf("\n");	  
  for(j=0;j<2;j++)	    
    {
      printf("%d\t",x_transpose[i][j]);
    }
    }
}









//function_transpose

int **transpose(int **x,int m,int n)
{
  int nrows=n,ncolumns=m,i,j;

  //memory allocation for y,to store transpose
  int **y;
  y = malloc(nrows * sizeof(int *));
  if(y == NULL)
    {
      printf("out of memory\n");
      return 0;
    }
  for(i = 0; i < nrows; i++)
    {
      y[i] = malloc(ncolumns * sizeof(int));
      if(y[i] == NULL)
	{
	  printf("out of memory\n");
	  return 0;
	}	  
    }




 
  for(i=0;i<m;i++)
    for(j=0;j<n;j++)
      {
	y[i][j]=x[j][i];
      }
  return y;
}

i allocated memory for storing y(transpose of matrix) inside the function. also i allocated memory(for x_transpose) for storing the same result in main program. can reuse the same memory in main also?
 
  • #23
is there any alternative for wavread (in matlab) in c. i want to get the samples, sampling frequency and bits per sample?
 
  • #24


vineeshvs said:
I allocated memory for storing y(transpose of matrix) inside the function. also i allocated memory(for x_transpose) for storing the same result in main program.
You only want to allocate the memory once. If you allocate in main program, then pass the pointer to transpose() and use it instead of reallocating.
 
  • #25
ok. then should i completely avoid x_transpose in main program and use only transpose instead?? then to which location should i store the pointer returned from function?? and for displaying the transpose can i use
Code:
transpose[i][j]
in the place of
Code:
x_transpose[i][j]
?
 
  • #26
If you want the main to allocate the space, then you need to pass it as a parameter:

Code:
// declare and allocate x_transpose
int x_transpose = malloc(...):
//  call function
    transpose(x_transpose,array,nrows,ncolumns);

If you want the function to allocate the space:

Code:
// declare but don't allocate x_transpose
int **x_transpose;
// call function
    x_transpose= transpose(array,nrows,ncolumns);
 
  • #27
If you run this with a debugger enabled, it should indicate what line the error occurred at, as well as being able to display values of variables and pointers.
 
  • #28
i am doing coding in emacs. does it have a debugger??
 
  • #29
Code:
#include <stdio.h>

#include<stdlib.h>
int **matrix_mul(int **m1,int **m,int a,int b,int c,int d);

main()

{

  int i,j,r1,r2,c1,c2,**p,**q;
printf("Enter the number of rows and columns of first matrix :\t");

scanf("%d%d",&r1,&c1);

printf("Enter the number of rows and columns of second matrix :\t");

scanf("%d%d",&r2,&c2);  //memory allocation for m1

int **m1;

  m1 = malloc(r1 * sizeof(int *));

  if(m1 == NULL)

    {

      printf("out of memory\n");

      return 0;

    }

  for(i = 0; i < r1; i++)

    {

      m1[i] = malloc(c1 * sizeof(int));

      if(m1[i] == NULL)

	{

	  printf("out of memory\n");

	  return 0;

	}	  

    }

//memory allocation for m1

int **m2;

  m2 = malloc(r2 * sizeof(int *));

  if(m2 == NULL)

    {

      printf("out of memory\n");

      return 0;

    }

  for(i = 0; i < r2; i++)

    {

      m2[i] = malloc(c2 * sizeof(int));

      if(m2[i] == NULL)

	{

	  printf("out of memory\n");

	  return 0;

	}	  

    }

if(c1==r2)

{

printf("Enter the elements of first matrix :\t");

for(i=0;i<r1;i++)

{

for(j=0;j<c1;j++)

{

scanf("%d \t",&m1[i][j]);

}

}  printf("Enter the elements of second matrix :\n");

for(i=0;i<r2;i++)

{

for(j=0;j<c2;j++)

{

scanf("%d \n",&m2[i][j]);

}

}
printf("\n first matrix is:");

for(i=0;i<r1;i++)

{

for(j=0;j<c1;j++)

{

printf("%d \t",m1[i][j]);

}

}  

printf("\n second matrix is:");

for(i=0;i<r2;i++)

{

for(j=0;j<c2;j++)

{

printf("%d \t",m2[i][j]);

}

}p=matrix_mul(m1,m2,r1,c1,r2,c2);for(i=0;i<r1;i++)
for(j=0;j<c2;j++)
q=(1/2*100)*p[i][j];//display result
for(i=0;i<r1;i++)

{

for(j=0;j<c2;j++)

{

printf("%d\n",q[i][j]);

}

getchar();

}
}
else

printf("Multiplication not possible.\n");

getchar();

}//FUNCTION_matrix_mul

int **matrix_mul(int **m1,int **m2,int r1,int c1,int r2,int c2 )

{

  int i,j,k;

//memory allocation to store product

int **p;

  p = malloc(r1 * sizeof(int *));

  if(p == NULL)

    {

      printf("out of memory\n");

      return 0;

    }

  for(i = 0; i < r1; i++)

    {

      p[i] = malloc(c2 * sizeof(int));

      if(p[i] == NULL)

	{

	  printf("out of memory\n");

	  return 0;

	}	  

    }  //product
for(i=0;i<r1;i++)

{

for(j=0;j<c2;j++)

{

p[i][j]=0;

for(k=0;k<r2;k++)

{

p[i][j]=p[i][j]+(m1[i][k]*m2[k][j]);

}

}

} return p;

}
in the above matrix multiplication problem i find the product matrix and store the it in the memory location pointed by p. now i want to multiply each element in product by 50. i no longer need p but need only q. will it be ok if i declare q as
Code:
int **q;
without allocating separate memory for q? will the elements of p in the corresponding location be replaced by elements of q?
 
  • #30
vineeshvs said:
Code:
   /* [...] */
   int nrows=2,ncolumns=2,i,j,k=0;
   /* [...] */
  int **array;
  array = malloc(nrows * sizeof(int *));
  if(array == NULL)
    {
      printf("out of memory\n");
      return 0;
    }

  
  for(i = 0; i < nrows; i++)
    {
      array[i] = malloc(ncolumns * sizeof(int));
      if(array[i] == NULL)
	{
	  printf("out of memory\n");
	  return 0;
	}
    }
/* [...] */

That ptrptring with explicit mallocing is sort-of obsolete since C99.
Code:
int array[nrows][ncolumns];
is valid C as of '99.

Standard C++ doesn't allow that, although some compilers also accept that syntax.
 
Last edited:

FAQ: Passing a 2d array to a function in C

How do I pass a 2d array to a function in C?

To pass a 2d array to a function in C, you need to declare the function parameter as a pointer to a 2d array. This can be done by specifying the size of the columns in the array, but leaving the size of the rows unspecified. For example:
void myFunction(int (*arr)[5]) {
// code goes here
}

Can I pass a 2d array to a function without specifying the number of columns?

Yes, you can pass a 2d array to a function without specifying the number of columns. This can be done by declaring the function parameter as a pointer to a pointer, and then using a loop to access the elements of the array. For example:
void myFunction(int **arr) {
// code goes here
}

How do I access elements of a 2d array passed to a function in C?

To access elements of a 2d array passed to a function in C, you can use the standard array indexing notation. For example, to access the element at row i and column j, you can use arr[i][j].

Can I modify a 2d array passed to a function in C?

Yes, you can modify a 2d array passed to a function in C. When an array is passed to a function, a copy of the array is created. Therefore, any changes made to the array within the function will also be reflected in the original array.

Is it possible to return a 2d array from a function in C?

No, it is not possible to return a 2d array from a function in C. You can only return a single value or a pointer to an array from a function. However, you can pass a 2d array to a function and modify it within the function, as mentioned in the previous question.

Similar threads

Back
Top