Passing a 2d array to a function in C

Click For Summary
SUMMARY

This discussion focuses on passing dynamically allocated 2D arrays to functions in C, specifically in the context of implementing a Game of Life simulation. The primary method involves passing a pointer to the array along with its dimensions as separate arguments. The participants provide sample code demonstrating memory allocation and array manipulation, while also discussing the potential for using C++ with standard containers like std::deque for easier management of dynamic arrays. Key insights include the importance of correctly freeing allocated memory and the ability to create jagged arrays and higher-dimensional arrays.

PREREQUISITES
  • Understanding of C programming syntax and memory management
  • Familiarity with dynamic memory allocation using malloc and free
  • Knowledge of pointers and how they relate to arrays in C
  • Basic grasp of function definitions and parameter passing in C
NEXT STEPS
  • Explore advanced memory management techniques in C, including realloc and free
  • Learn about creating and manipulating jagged arrays in C
  • Investigate the use of C++ standard containers, particularly std::deque for dynamic arrays
  • Study the implementation of multi-dimensional arrays in C and their memory allocation strategies
USEFUL FOR

Programmers working with C who need to manage dynamic arrays, game developers implementing simulations, and anyone interested in optimizing memory usage in C applications.

31si
Messages
21
Reaction score
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
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 arguments.
 
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?
 
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;
}
 
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)
 
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
 
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.
 
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.
 
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?
 
  • #12
  • #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:

Similar threads

  • · Replies 2 ·
Replies
2
Views
2K
Replies
20
Views
2K
Replies
2
Views
2K
Replies
3
Views
3K
  • · Replies 17 ·
Replies
17
Views
3K
  • · Replies 31 ·
2
Replies
31
Views
3K
  • · Replies 15 ·
Replies
15
Views
5K
  • · Replies 20 ·
Replies
20
Views
3K
  • · Replies 6 ·
Replies
6
Views
2K
  • · Replies 4 ·
Replies
4
Views
2K