View Full Version : Passing a 2d array to a function in C
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 any one know how to do this?
mgb_phys
Nov8-08, 12:06 PM
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.
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 lets 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?
mathmate
Nov8-08, 03:24 PM
Try:
#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;
}
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
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.
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.
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.
Another quick Q. How would I then free the allocated memory once I have done with it?
mathmate
Nov8-08, 04:28 PM
It's basically the same way you malloc'ed it, in two steps, but in reverse.
If you look up the reference, there is an example for it.
Ref : http://www.eskimo.com/~scs/cclass/int/sx9b.html
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)
Never mind sorted the different dimension problem
mathmate
Nov8-08, 04:52 PM
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!
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.
mathmate
Nov8-08, 06:14 PM
Great!
Let us know from time to time how you're doing.
Will do, I will most likely end up asking more questions about it anyway.
vineeshvs
Jan14-11, 10:58 PM
#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
if(x[i]=NULL)
one of the issues with C's syntax (some compilers will optionally generate a warning for this), make that
if(x[i]==NULL)
You can also do this with a single allocation:
// 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);
vineeshvs
Jan15-11, 02:33 AM
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 dont use that, will it reduce memory much for ordinary programs (i have 4GB RAM)??
vineeshvs
Jan15-11, 02:41 AM
#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???
vineeshvs
Jan15-11, 03:10 AM
is there any alternative for wavread (in matlab) in c. i want to get the samples, sampling frequency and bits per sample???
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.
vineeshvs
Jan15-11, 10:29 AM
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
transpose[i][j]
in the place of x_transpose[i][j]
???
If you want the main to allocate the space, then you need to pass it as a parameter:
// 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:
// declare but dont allocate x_transpose
int **x_transpose;
// call function
x_transpose= transpose(array,nrows,ncolumns);
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.
vineeshvs
Jan17-11, 05:25 AM
i am doing coding in emacs. does it have a debugger??
vineeshvs
Jan17-11, 05:25 AM
#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
int **q;
without allocating separate memory for q??? will the elements of p in the corresponding location be replaced by elements of q???
vBulletin® v3.8.7, Copyright ©2000-2012, vBulletin Solutions, Inc.