memcpy() for variable dimensions of a 3D array - c

I have a function concat to concatenate the matrix mat1 to form mat2. Here mat1 and mat2 uses fixed dimensions (i.e DIM1 = 2, DIM2 = 2, DIM3 = 3, DIM1_1 = 4) but in practice I need them to be of variable dimensions, so I declared the size of 3d array to max size as commented in my code below (i.e DIM2 = 20, DIM3 = 30) but the program gives garbage value when I do this. Could someone please advise on how to use variable sized 3d arrays without using malloc() ?
#include <stdio.h>
#include <string.h>
//!< Dimensions of a 3d array
#define DIM1 2
#define DIM2 2
#define DIM3 3
#define DIM1_1 4
void Concat(int (*mat1)[DIM2][DIM3], int (*mat2)[DIM2][DIM3], int len);
// void Concat(int (*mat1)[20][30], int (*mat2)[20][30], int len);
int main()
{
int mat1[DIM1][DIM2][DIM3] = {{{1,2,3},{4,5,6}},{{1,2,3},{4,5,6}}};
int mat2[DIM1_1][DIM2][DIM3];
Concat(mat1,mat2,2);
return 0;
}
// void Concat(int (*mat1)[20][30], int (*mat2)[20][30], int len){
void Concat(int (*mat1)[DIM2][DIM3], int (*mat2)[DIM2][DIM3], int len){
/*concatenate mat1 to mat2 */
memcpy(mat2[0], mat1, DIM1*DIM2*DIM3 * sizeof mat1);
memcpy(mat2[0+len], mat1, DIM1*DIM2*DIM3 * sizeof mat1);
}

I declared the size of 3d array to max size as commented in my code below (i.e DIM2 = 20, DIM3 = 30) but the program gives garbage value when I do this.
And I hope that before getting garbage values at runtime, your compiler warned you about the type mismatch that you created that way. If it didn't, then you would be well served by figuring out how to turn up the warning level, or else by choosing a more helpful compiler.
Either way, the parameters to your Concat() function are pointers to 2D arrays of specific dimensions. If the actual arguments are pointers to something else, even arrays of different dimension, then it should not come as a surprise that the results are poor. In fact, this produces a violation of the so-called "strict aliasing rule", and the behavior is therefore undefined.
Could someone please advise on how to use variable sized 3d arrays without using malloc() ?
I interpret you to mean you want a single function that works for arrays of various dimensions, not that any individual array has dimensions that change over time. There are several things you can do, but here are some good alternatives:
If your implementation supports VLAs (mandatory in C99, but optional since C11) then you can use them to support your Concat() function. This kind of thing is one of my favorite uses for VLAs, inasmuch as it sidesteps the biggest practical concern with their usage, which revolves around space available for their automatic allocation. Such an approach might look like this:
void Concat(size_t dim1, size_t dim2, size_t dim3 int (*source)[dim2][dim3],
int (*dest)[dim2][dim3]) {
size_t source_size = dim1 * sizeof(*source);
memcpy(dest, source, source_size);
memcpy(dest + dim1, source, source_size);
}
You will note that this requires you to pass all the dimensions of the source array as separate arguments, and that all dimensions but the first match for the two arrays. You would use that pretty simply:
int mat1[DIM1][DIM2][DIM3] = /* ... */
int mat2[DIM1 * 2][DIM2][DIM3];
Concat(DIM1, DIM2, DIM3, mat1, mat2);
Of course, you can use the same function, in the same program, to concatenate pairs of arrays of various dimensions, provided the constraints already described are satisfied.
If you cannot or do not want to rely on VLAs, then your best alternative might be simply to adapt the above to that case, like so:
void Concat(size_t dim1, size_t dim2, size_t dim3, void *source, void *dest) {
size_t source_size = dim1 * dim2 * dim3 * sizeof(int);
memcpy((char *) dest, source, source_size);
memcpy((char *) dest + source_size, source, source_size);
}
You could call that function the same way as the previous.
If you want to be even more general, and at the same time provide a simpler function signature, you could convert the above to concatenate arbitrary objects:
void Concat(size_t source_size, void *source, void *dest) {
memcpy((char *) dest, source, source_size);
memcpy((char *) dest + source_size, source, source_size);
}
This achieves complete generality by putting responsibility on the caller for computing and passing the size of the source object, in bytes, though that's not necessarily a big problem. For example,
int mat1[DIM1][DIM2][DIM3] = /* ... */
int mat2[DIM1 * 2][DIM2][DIM3];
Concat(sizeof(mat1), mat1, mat2);

I'm sorry, but it cannot be done (without knowing the maximum length in advance). When your function makes mat1, it reserves precisely 2*2*3 ints-worth of memory on the stack for the array, and sticks each sub-array right next to each other. If statically allocated, there's no way to change this after it's been done.
However... with dynamic memory allocation (i.e. malloc and friends) it's possible to do this. Specifically, using realloc to allocate extra space.
Sorry.

Related

C - How to declare an object type of arbitrary byte size?

I want to loop over arrays in a type-independent manner by casting a void pointer to an array of objects of arbitrary byte size. I know the size of the array and the size of its items, but not the type of the items. Is there a safe and portable way of doing this?
All I can think of at the moment is to create a struct with one member, a char array of the required size. But I'm not sure how safe and portable this is as a solution, due to possibility of alignment issues and possibly other problems I haven't thought of.
Example code of what I want to do:
void myFunc(void * arrV, int len, size_t arrSize, size_t itemSize) {
// type definition, for array item of size itemSize
struct xxxx {char[itemSize];};
struct xxxx * arr = (struct xxxx *) arrV;
for (int i = 0; i < len; i++) {
if (i == 100) {
struct xxxx arrItem = arr[i];
// do something with arrItem;
}
}
}
Edit: question title edited as it was phrased incorrectly.
Use malloc to allocate memory
void * itemArr = malloc(arrSize * itemSize);
malloc dynamically allocates memory equal to the size of its first parameter (in bytes).
Once you are done with using it, you can free that memory to make it usable again.
free(itemArr);
Edit: Ok here is trial 2
I do not think this:
struct xxxx {char[itemSize];};
is valid syntax in C, you need to have an identifier.
Also my argument still stands, if you want to create an object from an unknown type of arbitrary size, you can use malloc instead of a normal array. Use malloc, cast it to a void* or char*, and treat it as an unknown data type. A struct, or for that matter data types, are all abstractions. You can treat any piece of memory as a non-standard data type. Also as far as I know malloc shouldn't cause alignment issues as malloc pointers are always aligned
The size of a structure has to be known at compile time. You can have a flexible array member (FAM and more FAM) in a structure, but that doesn't help, not least because the size of the structure doesn't include the size of the FAM. Your attempt to create a type struct xxxx with a size determined at run time is doomed.
The C standard has two functions that process arrays of arbitrary type and size: bsearch() and qsort(). They use void *base to point to the start of the array, size_t count to specify how many elements are in the array and size_t size to specify the size of each element:
void qsort(void *base, size_t count, size_t size,
int (*compar)(const void *, const void *));
These functions both take a pointer to a function that compares two values in the array by whatever mechanism the function chooses.
To achieve your goal, you will need to emulate them. You've not specified how you expect to process the values in the array, and that would give you headaches unless you adopt a similar technique where you pass a pointer to each element of the array to a function.
You can process an array of arbitrary type and size with ordinary pointer arithmetic. Despite what the GCC compiler permits, Standard C says you can't do arithmetic on void * values, but you can do arithmetic on char * values. As long as the size of the items is the result of sizeof(TheActualType), you can step through data that is appropriately aligned. I'm assuming that in your interface, arrSize == len * itemSize (see also my comment), though that's barely critical as I redesign the interface to your function to more closely match the standard functions. I add a callback function which is given a void * argument that can be safely cast to whatever type is being processed:
void ProcessArray(void *base, size_t count, size_t size, void (*processor)(void *))
{
char *array = base;
for (int i = 0; i < len; i++)
{
(*processor)(array + i * itemSize);
}
}
The function pointer should be of the type shown. Many people take the shortcut of defining a processing function such as void ProcessingFunction(SomeType *arg); and passing that to a function. That includes such prestigious references as Brian W Kernighan and Dennis M Ritchie
The C Programming Language, 2nd Edn (1988). But the C standard says (in §6.3.2.3 (Conversions of) Pointers) that calling a pointer to a function with the wrong type is undefined behaviour. So, strictly, you should not pass such a function to a function like ProcessArray(). You need a function like:
void ProcessingFunction(void *arg)
{
SomeType *ptr = arg; /* Cast not necessary in C */
…process data using ptr->member…
}
If need be, you can pass a 'context' pointer to the functions to convey information other than the element being processed to the processing function:
void ProcessArrayWithContext(void *base, size_t count, size_t size, void (*processor)(void *arg, void *context), void *context)
{
char *base = arrV;
for (int i = 0; i < len; i++)
{
(*processor)(base + i * itemSize, context);
}
}
And then:
void ProcessingFunctionWithContext(void *arg, void *context)
{
SomeType *ptr = arg; /* Cast not necessary in C */
ContextInfo *ctxt = context;
…process data using ptr->member and ctxt->info…
}
There is precedent for this with the non-standard qsort_r() functions defined by Linux and BSD (macOS). However, be aware that the BSD and Linux interfaces to qsort_r() are different. The Linux version looks like:
void qsort_r(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *, void *),
void *arg);
The comparator takes the context as the third, non-const argument, and qsort_r() passes arg as that third argument. The BSD version looks like:
void qsort_r(void *base, size_t nel, size_t width, void *thunk,
int (*compar)(void *, const void *, const void *));
The comparator takes the context as the first, non-const argument, and the context is passed before the pointer to the comparator.
In the Linux code, the function effectively contains:
void *v1 = …;
void *v2 = …;
int rc;
if ((rc = (*compar)(v1, v2, arg)) < 0)
…
else if (rc > 0)
…
else
…
The BSD effectively contains:
void *v1 = …;
void *v2 = …;
int rc;
if ((rc = (*compar)(arg, v1, v2)) < 0)
…
else if (rc > 0)
…
else
…
See also Pass extra parameter to comparator for qsort()?.
Obviously, the callback (processing) function could be given other types. For example, you might have it return a value of type int and the loop could exit early if the value returned is not 0, or if it is 0. The options are legion.
I want to loop over arrays in a type-independent manner by casting a void pointer to an array of objects of arbitrary byte size. I know the size of the array and the size of its items, but not the type of the items. Is there a safe and portable way of doing this?
It depends on how portable you need it to be. Your suggestion of an defining a structure type containing an array of the desired length is not viable for two reasons:
In standard C, structure types may not be defined as containing variable-length arrays, and
There is no portable way to ensure that the structure type would not contain padding (which would make its size wrong).
Additionally, the variable-length array feature is optional in C11 and C17 (though it is a mandatory in C99, and some form of it might return to mandatory status in C2X). But if you are willing to rely on VLAs then you can use them more directly for your purpose:
void myFunc(void *arrV, int len, size_t arrSize, size_t itemSize) {
char (*items)[itemSize] = arrV; // pointer to (variable-length) array
for (int i = 0; i < len; i++) {
// ... do something with items[i] ...
}
}
If you don't want to depend on VLAs then the conventional way that functions such as qsort() do it is to convert the void * to a char * and perform appropriate arithmetic with that:
void myFunc(void *arrV, int len, size_t arrSize, size_t itemSize) {
char *items = arrV;
for (int i = 0; i < len; i++) {
char *item_start = items + (i * itemSize);
// ... do something with *item_start
}
}

Declare global contiguous 2d array at runtime. The dimensions are unknown at compile time C

I want to declare a global 2d array in C, and allocate contiguous memory at runtime because the minor dimension is unknown at compile time.
I would like to dereference the array with 2-indices notation A[i][j].
If the array wasn't global c99 notation "double A[m][n]" would be handy but in my case does not apply.
What would be the right strategy?
#include <stdio.h>
#include <stdlib.h>
//TO DO
//DECLARE array here
void fun1() {
array[3][2] = 42.0;
}
int main(int argc,char *argv[])
{
int rows = atol(argv[1]);
int cols = atol(argv[2]);
//TO DO
//Allocate memory for array here
fun1();
printf("Array[3][2]=%f\n",array[3][2]);
return(0);
}
Unfortunately, it not quite possible in C to achieve what you are asking for.
There is a slightly ugly solution with a macro. Since the macro refers to both the global array itself and a global variable containing its second dimension, you have to be careful to not shadow the globals in any function which uses the macro. Here, I used clunky names ending with underscores to try to avoid name reuse.
Other than that, it should work:
void* global_array_void_;
size_t global_array_minor_dim_;
#define global_array ((double(*)[global_array_minor_dim_])global_array_void_)
Before you can use the macro, you need to allocate it and initialize the global variables:
void init_global_array(int rows, int cols) {
global_array_minor_dim_ = cols
global_array_void_ = malloc(rows * cols * sizeof global_array[0][0]);
}
From then on, you can use use global_array as though it were a regular array:
void f(int r, int c, double v) {
global_array[r][c] = v;
}
Live on coliru.
The type in the cast ((double (*)[cols])(array_void_)) might not be obvious. It represents a pointer to an array of cols doubles, which is what double[][cols] would decay to as a pointer. Note that double[][cols] does not decay to double**, which is a completely different (and incompatible) type.
With that definition, sizeof global_array[r] has the correct value: cols * sizeof(double). Contrast that with sizeof argv[i].
A more traditional way of doing this is to use a function to compute the precise index. That still depends on the minor dimension being available:
double* global_array;
size_t global_array_minor_dim_;
void init_global_array(int rows, int cols) {
global_array_minor_dim_ = cols
global_array_void_ = malloc(rows * cols * sizeof global_array[0][0]);
}
double* global_array_at(int r, int c) {
return &global_array[r * global_array_minor_dim_ + c];
}
Now you can use *global_array_at(r, c) as a replacement for global_array[r][c]. In C, it's impossible to eliminate the * and still have assignment work (in C++, the function could have returned a double& instead of a double*), but this could be solved, once again, with a macro.
Here is a sample for you to follow:
#include <stdlib.h>
void main(void)
{
int **f;
int n = 2, m = 3;
f = (int **)malloc(sizeof(int)*n *m);
f[1][2] = 3;
}

Segmentation fault when printing contents of a multidimensional array

I'm running the following C program and getting Segmentation fault: 11.
#include <stdio.h>
#include <stdlib.h>
#define SIZE 2
void print_array(double **arr, int size) {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
printf("%f\n", arr[i][j]);
}
}
}
int main(int argc, char **argv) {
double mat[SIZE][SIZE] = {{1, 2}, {3, 4}};
print_array((double **) mat, SIZE);
}
Could someone explain why this might be happening? I don't believe that I need to dynamically allocate memory for mat, since I'm passing it into print_array within the main() function.
When changing the function signature of print_array() to
void print_array(int size, double arr[size][size])
the problem goes away.
Still curious though... Why do I get the segmentation fault when casting mat as double ** and passing it into print_array()? At the end of the day, double arr[2][2] and double **arr with size 2 are the same thing, correct?
You're getting undefined behavior since you're lying to the compiler about what your memory contains.
The in-memory format of mat is not the same as (double **). The former is a compact square of doubles, the latter is a pointer to a pointer. These are not the same.
You can represent a 2D as an array of row (or column, if you feel like it) pointers, which makes double indexing work. But that isn't the same thing as indexing into an actual array.
UPDATE: I'm not sure if it's possible to come up with a function signature for a function that can access either an actual compact array, or one represented through pointers ... My suggestion would be to keep it simple and write two different functions for these different requirements:
void print_matrix_compact(const double *el0, size_t size);
void print_matrix_indirect(const double **mtx, size_t size);
Here el0 is a pointer to element 0 of an actual ("compact") array, while mtx is a pointer to an array of pointers for the one stored as an array of arrays. In both cases matrices are assumed to be square, with a size of size×size elements.
No, they are not the same.
A double[size][size] is a contiguous block of memory containing doubles where the compiler knows how to calculate the addresses out of the indices.
A double ** is a pointer to a block of memory containing one or more pointers to blocks of doubles.
By accessing the double[size][size] as double ** you are interpreting your double values as pointers.

Passing dynamically allocated array as a parameter in C

So... I have a dynamically allocated array on my main:
int main()
{
int *array;
int len;
array = (int *) malloc(len * sizeof(int));
...
return EXIT_SUCCESS;
}
I also wanna build a function that does something with this dynamically allocated array.
So far my function is:
void myFunction(int array[], ...)
{
array[position] = value;
}
If I declare it as:
void myFunction(int *array, ...);
Will I still be able to do:
array[position] = value;
Or I will have to do:
*array[position] = value;
...?
Also, if I am working with a dynamically allocated matrix, which one is the correct way to declare the function prototype:
void myFunction(int matrix[][], ...);
Or
void myFunction(int **matrix, ...);
...?
If I declare it as:
void myFunction(int *array, ...);
Will I still be able to do:
array[position] = value;
Yes - this is legal syntax.
Also, if I am working with a dynamically allocated matrix, which one
is correct to declare the function prototype:
void myFunction(int matrix[][], ...);
Or
void myFunction(int **matrix, ...);
...?
If you're working with more than one dimension, you'll have to declare the size of all but the first dimension in the function declaration, like so:
void myFunction(int matrix[][100], ...);
This syntax won't do what you think it does:
void myFunction(int **matrix, ...);
matrix[i][j] = ...
This declares a parameter named matrix that is a pointer to a pointer to int; attempting to dereference using matrix[i][j] will likely cause a segmentation fault.
This is one of the many difficulties of working with a multi-dimensional array in C.
Here is a helpful SO question addressing this topic:
Define a matrix and pass it to a function in C
Yes, please use array[position], even if the parameter type is int *array. The alternative you gave (*array[position]) is actually invalid in this case since the [] operator takes precedence over the * operator, making it equivalent to *(array[position]) which is trying to dereference the value of a[position], not it's address.
It gets a little more complicated for multi-dimensional arrays but you can do it:
int m = 10, n = 5;
int matrixOnStack[m][n];
matrixOnStack[0][0] = 0; // OK
matrixOnStack[m-1][n-1] = 0; // OK
// matrixOnStack[10][5] = 0; // Not OK. Compiler may not complain
// but nearby data structures might.
int (*matrixInHeap)[n] = malloc(sizeof(int[m][n]));
matrixInHeap[0][0] = 0; // OK
matrixInHeap[m-1][n-1] = 0; // OK
// matrixInHeap[10][5] = 0; // Not OK. coloring outside the lines again.
The way the matrixInHeap declaration should be interpreted is that the 'thing' pointed to by matrixInHeap is an array of n int values, so sizeof(*matrixInHeap) == n * sizeof(int), or the size of an entire row in the matrix. matrixInHeap[2][4] works because matrixInHeap[2] is advancing the address matrixInHeap by 2 * sizeof(*matrixInHeap), which skips two full rows of n integers, resulting in the address of the 3rd row, and then the final [4] selects the fifth element from the third row. (remember that array indices start at 0 and not 1)
You can use the same type when pointing to normal multidimensional c-arrays, (assuming you already know the size):
int (*matrixPointer)[n] = matrixOnStack || matrixInHeap;
Now lets say you want to have a function that takes one of these variably sized matrices as a parameter. When the variables were declared earlier the type had some information about the size (both dimensions in the stack example, and the last dimension n in the heap example). So the parameter type in the function definition is going to need that n value, which we can actually do, as long as we include it as a separate parameter, defining the function like this:
void fillWithZeros(int m, int n, int (*matrix)[n]) {
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++j)
matrix[i][j] = 0;
}
If we don't need the m value inside the function, we could leave it out entirely, just as long as we keep n:
bool isZeroAtLocation(int n, int (*matrix)[n], int i, int j) {
return matrix[i][j] == 0;
}
And then we just include the size when calling the functions:
fillWithZeros(m, n, matrixPointer);
assert(isZeroAtLocation(n, matrixPointer, 0, 0));
It may feel a little like we're doing the compilers work for it, especially in cases where we don't use n inside the function body at all (or only as a parameter to similar functions), but at least it works.
One last point regarding readability: using malloc(sizeof(int[len])) is equivalent to malloc(len * sizeof(int)) (and anybody who tells you otherwise doesn't understand structure padding in c) but the first way of writing it makes it obvious to the reader that we are talking about an array. The same goes for malloc(sizeof(int[m][n])) and malloc(m * n * sizeof(int)).
Will I still be able to do:
array[position] = value;
Yes, because the index operator p[i] is 100% identical to *(ptr + i). You can in fact write 5[array] instead of array[5] and it will still work. In C arrays are actually just pointers. The only thing that makes an array definition different from a pointer is, that if you take a sizeof of a "true" array identifier, it gives you the actual storage size allocates, while taking the sizeof of a pointer will just give you the size of the pointer, which is usually the system's integer size (can be different though).
Also, if I am working with a dynamically allocated matrix, which one is the correct way to declare the function prototype: (…)
Neither of them because those are arrays of pointers to arrays, which can be non-contigous. For performance reasons you want matrices to be contiguous. So you just write
void foo(int matrix[])
and internally calculate the right offset, like
matrix[width*j + i]
Note that writing this using the bracket syntax looks weird. Also take note that if you take the sizeof of an pointer or an "array of unspecified length" function parameter you'll get the size of a pointer.
No, you'd just keep using array[position] = value.
In the end, there's no real difference whether you're declaring a parameter as int *something or int something[]. Both will work, because an array definition is just some hidden pointer math.
However, there's is one difference regarding how code can be understood:
int array[] always denotes an array (it might be just one element long though).
int *pointer however could be a pointer to a single integer or a whole array of integers.
As far as addressing/representation goes: pointer == array == &array[0]
If you're working with multiple dimensions, things are a little bit different, because C forces you declare the last dimension, if you're defining multidimensional arrays explicitly:
int **myStuff1; // valid
int *myStuff2[]; // valid
int myStuff3[][]; // invalid
int myStuff4[][5]; // valid

passing a pointer to 2D array of pointers in C

I have seen some of the other answers on this topic but dont really understand them enough to fit them to my problem. I have a 2D array of pointers to char that I want to pass to a function.
If the array is declared: char *params[50][50]; (50 is just picked arbitrarily)
and the function prototype is: void test (char ***results);
How would I call the function? everything I try ends up with an incompatible pointer warning
Also what is the most correct way to then refer to the members of the array while inside the function? is it simply: results[x][y]; ?
Thanks
you can't, pointers to pointers and pointers to arrays are different things.
void test (char *results[50][50]);
void test (char *results[][50]);
void test (char *(*results)[50]);
are all equivalent prototypes for the function that you are looking for.
Suplement: If you want to use the same function for arrays with varying lenght for the dimension you'd have to use VLA (variable length array) as function arguments:
void test (size_t n, char *results[n][n]);
void test (size_t n, char *results[][n]);
void test (size_t n, char *(*results)[n]);
This only works if you have a compiler that is conforming to C99.
Observe that the parameter for the size comes before the array, such that it is known there.
Also you don't have to declare the arrays themselves with variable length to use this feature for the function parameters. But if you do be careful that you don't allocate large matrices on the stack, otherwise you may easily have a stackoverflow.
If you declare an array as
char *array[N][M];
and pass it to a function as
test(array)
then the prototype to the function will need to be either
void test(char *(*arr)[M])
or
void test(char *arr[][M])
In either case, arr has type "pointer to M-element array of pointer to char". This is not the same type as char ***, and there's no really good or clean way to convert between the two.
Had you allocated dynamcally allocated array in the following manner, then the prototype would be correct:
char ***array = malloc(sizeof *array * N);
if (array)
{
size_t i;
for (i = 0; i < N; i++)
{
array[i] = malloc(sizeof *array[i] * M);
if (array[i])
{
size_t j;
for (j = 0; j < M; j++)
{
array[i][j] = some_initial_pointer_value();
}
}
}
}
Note that in this case, the type of array is char ***.
If you're working with arrays declared as T a[M][N], and you want to write a function that will accept arrays of different sizes, then you can either use the VLA syntax as suggested by Jens, or you could do something like this:
void test(char **a, size_t rows, size_t cols)
{
size_t i, j;
...
some_pointer_value = a[i * rows + j];
...
a[i * rows + j] = some_pointer_value;
}
...
test(&array[0][0], 50, 50);
In this case, we explicitly pass the address of the first element of the array and the array dimensions as separate parameters. Within the body of test we treat the array as having 1 dimension (char *a[rows * cols]) and compute the offset manually. Note that this only works for arrays that are contiguously allocated; this won't work with the version that does piecemeal allocation for each row in the array above.
My C is a little rusty but:
char *params[][];
is a 2D array of char * pointer, not char. If you wanted a 2D char array it is defined as:
char params[valuex][valuey];
Iit will be static memory allocation, only available in definition scope, i mean you leave the scope you loose the array if it is not the behaviour you are looking for try dynamic allocation).
You can then pass this array to a function by defining the function prototype as:
void foo(char param[valuex][valuey] );
Regards

Resources