Return a dynamically allocated array? (C) - c

Consider the given 2d array allocation:
int (*some)[10] = malloc(sizeof(int[10][10]));
This allocates a 10 x 10 2d array. Apparently its type is int (*)[10]. I want to write a function initialize() that will allocate it, initialize it and then return a pointer to the array, so that the construction some[i][j] would be usable in other functions which can pass a pointer to the array it onto each other.
What should the prototype, specifically the return type of initialize() be?

int (*initialize(void))[10] { ... }
initialize is a function, which takes no parameters and returns a pointer to an array of 10 int.
You should use a typedef for that.

allocates the table of nrow pointers to (allocated) int array of size elements
void *allocate_rows(int *(*ptr)[size], size_t nrows)
{
int (*tmpptr)[size] = *ptr;
*ptr = malloc(nrows * sizeof(*ptr));
if(*ptr)
{
while(nrows--)
{
tmpptr = malloc(sizeof(*tmpptr));
if(!tmpptr)
{
/* malloc failed do something */
}
else
{
tmpptr++;
}
}
return *ptr;
}

In
int (*some)[10] = malloc(sizeof *some);, some is a "pointer to an array of 10 int`.
If you want other to be a function returning a pointer to an array of of 10 int, you can start with int (*some)[10]; and replace some with what a call to a such function would look like to get your declaration.
int (*some)[10]; => int (*other(argument1,argument2))[10];
That's how it worked in pre-standardized C. Since standardized C has prototypes, you'd also replace the argument identifier list with a parameter type list, e.g.:
int (*other(int argument1, double argument2))[10];
The cdecl program or the cdecl website can help you verify the result:
$ echo 'explain int (*other(int,double))[10]'|cdecl
declare other as function (int, double) returning pointer to array 10 of int
Most people find typedefs more readable:
typedef int (*pointer_to_an_array_of_10_int)[10];
pointer_to_an_array_of_10_int other(int, double);
//to verify it's a compatible declaration
int (*other(int , double ))[10];

Related

How to return a 2D array?

I was searching for an efficient way to create a 2D array and return it, usually I make an array of pointers, allocate memory for each pointer, and return an **ptr. I was looking for another way to do it because then I have to free every single memory allocated.
I was reading online that you can allocate a 2D array like this: int (*arr)[n] = malloc( sizeof *arr * i );
In which ptr is a pointer, pointing to the adress of arr[n].
When I try to return arr, from the following function: int *array_of_smallest(int count);
I get: warning: assignment to ‘int *’ from incompatible pointer type ‘int (*)[n]’ [-Wincompatible-pointer-types]
If I initialise another pointer and point it to array, then return it, I'm only returning a 1D array.
I think I'm mixing diferent concepts and confusing myself.
With an array of pointers I don't have a problem, but I wanted a simplier way to create a 2D array, also easier to free, but I'm not being able to return that array from my function.
You declared a pointer of the variable modified type type int ( * )[n].
int (*arr)[n] = malloc( sizeof *arr * i );
That is the variable n used in the declarator is not an integer constant expression.
In this case the function should have the return type void *. And it can be declared like
void * array_of_smallest(int count)
{
int (*arr)[n] = malloc( sizeof *arr * i );
//...
return arr;
}
In the caller you will write
int ( *arr )[n] = array_of_smallest( count );
In this declaration the value of n must be the same as used within the function.
If to use an integer constant expression like
int (*arr)[2] = malloc( sizeof *arr * 2 );
then the function declaration will look like
int ( * array_of_smallest(int count) )[2];
Or you can introduce a typedef name before the function declaration like
typedef int Array[2];
and in this case the function will look like
Array * array_of_smallest(int count);
The fundamental issue with returning the array is that it is not possible to declare Variably-Modified Type (like a pointer to VLA) at the file scope.
The reason of the problem can be explained as follow. Your code behaves more or less like this:
typedef int T[n];
T* array_of_smallest(int count) { ... }
Unfortunately, defining such a type T is not possible because of two reasons:
n is usually not visible at file scope, except if it was a global variable
evaluation of n would require code execution at file scope which is forbidden
Workarounds
Return void* as described in other answer.
Pass a pointer to VLA in "by-reference" style, as a pointer to a pointer to array
void array_of_smallest(int count, int (**p)[n]) {
...
*p = arr;
}
Return a pointer to incomplete array type of int[]. It is not possible to return incomplete types but it is possible to return a pointer to incomplete types:
int (*array_of_smallest(int count))[] { ... }
or a bit cleaner with a help of typeof extension (feature in C23)
typeof(int[]) *array_of_smallest(int count) { ... }
And use it as in the void* case:
int ( *arr )[n] = array_of_smallest( count );
This solution provides type-checking for the element type, however it works only for 2-dimensional arrays.
Wrap the pointer into a structure and use a macro to reconstruct its type on the client side:
typedef struct {
int rows, cols;
void* data;
} Arr2D;
Arr2D array_of_smallest(int count) {
...
return (Arr2D) { .rows = i, .cols = n, .data = arr };
}
#define ARR2D_DEF_VIEW(view, arr2d) int (*view)[(arr2d).cols] = (arr2d).data
... usage ...
Arr2D arr = array_of_smallest(42);
ARR2D_DEF_VIEW(view, arr);
... do stuff with view[i][j]
}
Alternatively, use typeof extension to infer the type of VLA view rather than declare it in a macro:
#define ARR2D_VIEW_TYPE(arr2d) typeof(int(*)[(arr2d).cols])
...
Arr2D arr = array_of_smallest(42);
ARR2D_VIEW_TYPE(arr) view = arr.data;

How to make an array containing function pointers? [duplicate]

I've a little question.
I'm trying to define an array of function pointers dynamically with calloc.
But I don't know how to write the syntax.
Thanks a lot.
The type of a function pointer is just like the function declaration, but with "(*)" in place of the function name. So a pointer to:
int foo( int )
would be:
int (*)( int )
In order to name an instance of this type, put the name inside (*), after the star, so:
int (*foo_ptr)( int )
declares a variable called foo_ptr that points to a function of this type.
Arrays follow the normal C syntax of putting the brackets near the variable's identifier, so:
int (*foo_ptr_array[2])( int )
declares a variable called foo_ptr_array which is an array of 2 function pointers.
The syntax can get pretty messy, so it's often easier to make a typedef to the function pointer and then declare an array of those instead:
typedef int (*foo_ptr_t)( int );
foo_ptr_t foo_ptr_array[2];
In either sample you can do things like:
int f1( int );
int f2( int );
foo_ptr_array[0] = f1;
foo_ptr_array[1] = f2;
foo_ptr_array[0]( 1 );
Finally, you can dynamically allocate an array with either of:
int (**a1)( int ) = calloc( 2, sizeof( int (*)( int ) ) );
foo_ptr_t * a2 = calloc( 2, sizeof( foo_ptr_t ) );
Notice the extra * in the first line to declare a1 as a pointer to the function pointer.
I put a small example here that may help you
typedef void (*fp)(int); //Declares a type of a void function that accepts an int
void test(int i)
{
printf("%d", i);
}
int _tmain(int argc, _TCHAR* argv[])
{
fp function_array[10]; //declares the array
function_array[0] = test; //assings a function that implements that signature in the first position
function_array[0](10); //call the cuntion passing 10
}
You'd declare an array of function pointers as
T (*afp[N])();
for some type T. Since you're dynamically allocating the array, you'd do something like
T (**pfp)() = calloc(num_elements, sizeof *pfp);
or
T (**pfp)() = malloc(num_elements * sizeof *pfp);
You'd then call each function as
T x = (*pfp[i])();
or
T x = pfp[i](); // pfp[i] is implicitly dereferenced
If you want to be unorthodox, you can declare a pointer to an array of pointers to functions, and then allocate that as follows:
T (*(*pafp)[N])() = malloc(sizeof *pafp);
although you would have to deference the array pointer when making the call:
x = (*(*pafp)[i])();
typedef R (*fptr)(A1, A2... An);
where R is the return type, A1, A2... An are the argument types.
fptr* arr = calloc(num_of_elements,sizeof(fptr));
Assuming all your functions are of type void ()(void), something like this
typedef void (*fxptr)(void);
fxptr *ptr; // pointer to function pointer
ptr = malloc(100 * sizeof *ptr);
if (ptr) {
ptr[0] = fx0;
ptr[1] = fx1;
/* ... */
ptr[99] = fx100;
/* use "dynamic array" of function pointers */
free(ptr);
}

Acessing a 2D array inside a function

I have a function which accepts int* pInput[] as an argument.
void Process(int* pInput[], unsigned int num);
I have to call this function via 2 methods as
main()
{
int *pIn[2];
int input[2][100] = {0};
pIn[0] = ( int* )malloc( 100 * sizeof( int) );
pIn[1] = ( int* )malloc( 100 * sizeof( int) );
Process( pIn, 2 );
Process( ( int** )input, 2 );
}
Then how can i access each value of pInput inside function 'Process'?I cannot access it directly as pIn[0][0].
how can i access each value of pInput inside function 'Process'?I cannot access it directly as pIn[0][0].
No! You can access it exactly that way: pInput[0][0] if the input you pass is pIn. This is because pIn is an array of int*s I.e. it's of type int *[n] each of its element pointing to an array of ints. It would decay into int**.
However, if you want to pass input, a 2D array of ints, you've to do more since a 2D array doesn't decay into a double pointer, T** but into a pointer to an array, T (*) [n]. This is because array decay is not recursive, it happens only to the first level. Alternatively, you can do this (Live example)
pIn[0] = input[0];
pIn[1] = input[1];
and now pass pIn to Process. Here pIn is a surrogate for input and it needs to have as many elements as input, which is not a very elegant solution. A better way to pass input, when you know the dimensions during compile-time is
void Process(int (*pInput)[100], size_t rows) { }
void Process(int input [2][100], size_t rows) { }
/* These two are the same; the compiler never sees the `2`. input's type is int(*)[100] */
Read on array decay to understand the situation better.
Aside
Do I cast the result of malloc? No, you do not need to cast the return value of malloc in C.
What should main() return in C and C++? The return type of main should be int.
Related
C-FAQ: My compiler complained when I passed a two-dimensional array to a function expecting a pointer to a pointer.
What is array decaying?
Why can we omit the first dimension of a multidimensional array when we are passing it to a function
In your process() function you just need to access it normally like any 2d array as below. Calling both ways are same.
void Process( int * pInput[], unsigned int num)
{
printf(" %d", pInput[0][0]); //printing value of pInput[0]
printf(" %d", pInput[1][0]); //printing value of pInput[1]
pInput[0][0] = 8054; // changing its value.
pInput[1][0] = 8055; // changing its value.
}
int main()
{
int *pIn[2];
int input[2][100] = {0};
pIn[0] = ( int* )malloc( 100 * sizeof( int) );
pIn[1] = ( int* )malloc( 100 * sizeof( int) );
// assigning value to array.
pIn[0][0] = 23;
pIn[0][1] = 2;
pIn[1][0] = 5689;
pIn[1][1] = 5643;
Process( pIn, 2 ); //calling process funtion
printf(" %d", pIn[1][0]); //printing the changed value by process funtion.
}
You are getting confused because you are using different types when there's no need for such. Arrays follow the same rules of indirection as any other type. If you would allocate a plain int dynamically, you would write int* x = malloc(sizeof(*x));. Simply do the very same thing when it comes to arrays. Don't confuse things by mixing in the "arrays decay to pointers" rule.
So we have int input[2][100], very straight-forward, it is a plain 2D array. Now if you want to allocate that dynamically, you will need a pointer to such an array:
int (*pIn)[2][100]; // pointer to an array of int [2][100].
pIn = malloc(sizeof(*pIn));
And the whole program would then be:
#include <stdlib.h>
void Process (size_t num, int pInput[num][100])
{
}
int main (void)
{
int (*pIn)[2][100];
int input[2][100] = {0};
pIn = malloc(sizeof(*pIn));
if(pIn == NULL)
{
// error handling
return 0;
}
Process(2, *pIn);
Process(2, input);
free(pIn);
return 0;
}
Comments:
size_t is the most correct type to use for array sizes, as it is the type returned by the sizeof operator. So it is just an unsigned integer with a fancy name.
int pInput[num][100] in the function will actually decay into an array pointer to an array of 100 int. You don't need to know that to use it though, simply use pInput[x][y] and pretend it is a 2D array. The important thing here is to understand that the array is not passed by value.
The correct form of main is int main (void).
Casting the result of malloc is pointless.
Always check the result of malloc and remember to clean up allocated data.

Matrix power and pointers

I am trying to compute the power of the matrix A using multiplications.
I am having problems with the ArrayPower function. It does not function as i think it should.The MultiArray function however seems to work fine. Can anyone help me ?
#include <stdio.h>
int** MultiArray(int a[2][2],int b[2][2]);
int** ArrayPower(int a[2][2],int e);
int main(void)
{
int fa[2][2];
fa[0][0]=0;
fa[0][1]=1;
fa[1][0]=1;
fa[1][1]=1;
int **multifa=malloc(sizeof(int)*2);
for (int i=0;i<2;i++) {
multifa[i]=malloc(sizeof(int)*2);
}
multifa=ArrayPower(fa,2);
printf("%d %d\n",multifa[0][0],multifa[0][1]);
printf("%d %d\n",multifa[1][0],multifa[1][1]);
return 0;
}
int** MultiArray(int a[2][2], int b[2][2]) {
//multi a *b
//memory allocation
int i,rows=2,cols=2;
int **c=malloc(rows*sizeof(int));
for (i=0;i<rows;i++) {
c[i]=malloc(cols*sizeof(int));
}
c[0][0]=a[0][0]*b[0][0]+a[0][1]*b[1][0];
c[0][1]=a[0][0]*b[0][1]+a[0][1]*b[1][1];
c[1][0]=a[1][0]*b[0][0]+a[1][1]*b[1][0];
c[1][1]=a[1][0]*b[0][1]+a[1][1]*b[1][1];
return c;
}
int** ArrayPower(int a[2][2],int e) {
//memory allocation
int i,rows=2,cols=2;
int **c=malloc(rows*sizeof(int));
for (i=0;i<rows;i++) {
c[i]=malloc(cols*sizeof(int));
}
c[0][0]=a[0][0];
c[0][1]=a[0][1];
c[1][0]=a[1][0];
c[1][1]=a[1][1];
for (i=1;i<e;i++) {
c=MultiArray(a,c);
}
return c;
}
MultiArray is declared as taking a second parameter of type int [2][2], but it is called with an argument of c, which as type int **. These are not compatible types.
In a parameter, the type int [2][2] is automatically converted to a pointer to an array of two int, the type int (*)[2]. This is a pointer to a place where there are two int objects (and, because we know it is the first element of an array of two arrays of two int objects, we know there are two more int objects beyond the first two).
The definition of c with int **c means that c is a pointer to a pointer to an int. A pointer to a pointer and a pointer to an array are different and are not compatible.
One way to fix this is to define c with int (*c)[2] = malloc(2 * sizeof *c);. It is then unnecessary to have the loop after the definition that allocates more space; the single allocation allocates the entire array.
The return type of MultiArray should be changed similarly, as well as the code within it and elsewhere in the program. Alternatively, the second parameter of MultiArray can be changed from int b[2][2] to int **b. (This latter is an easier edit but produces an inferior program, since it uses more pointers and allocations than necessary.)
You should always compile your code with warnings enabled. That would have alerted you to the incorrect call.

What does the declaration void** mean in the C language?

I'm beginning to learn C and read following code:
public void** list_to_array(List* thiz){
int size = list_size(thiz);
void **array = malloc2(sizeof(void *) * size);
int i=0;
list_rewind(thiz);
for(i=0; i<size; i++){
array[i] = list_next(thiz);
}
list_rewind(thiz);
return array;
}
I don't understand the meaning of void**. Could someone explain it with some examples?
void** is a pointer to a pointer to void (unspecified type). It means that the variable (memory location) contains an address to a memory location, that contains an address to another memory location, and what is stored there is not specified. In this question's case it is a pointer to an array of void* pointers.
Sidenote: A void pointer can't be dereferenced, but a void** can.
void *a[100];
void **aa = a;
By doing this one should be able to do e.g. aa[17] to get at the 18th element of the array a.
To understand such declarations you can use this tool and might as well check a related question or two.
void** is a pointer to void*, or a pointer to a void pointer if you prefer!
This notation is traditionally used in C to implement a matrix, for example. So, in the matrix case, that would be a pointer to an array of pointers.
Normally void * pointers are used to denote a pointer to an unknown data type. In this case your function returns an array of such pointers thus the double star.
In C, a pointer is often used to reference an array. Eg the following assignment is perfectly legal:
char str1[10];
char *str2 = str1;
Now when void is used, it means that instead of char you have a variable of unknown type.
Pointers to an unknown data type are useful for writing generic algorithms. Eg. the qsort function in standard C library is defined as:
void qsort ( void * base,
size_t num,
size_t size,
int ( * comparator )
( const void *, const void * ) );
The sorting algorithm itself is generic, but has no knowledge of the contents of the data. Thus the user has to provide an implementation of a comparator that can deal with it. The algorithm will call the comparator with two pointers to the elements to be compared. These pointers are of void * type, because there is now information about the type of data being sorted.
Take a look at this thread for more examples
http://forums.fedoraforum.org/showthread.php?t=138213
void pointers are used to hold address of any data type. void** means pointer to void pointer. Void pointers are used in a place where we want a function should receive different types of data as function argument. Please check the below example
void func_for_int(void *int_arg)
{
int *ptr = (int *)int_arg;
//some code
}
void func_for_char(void *char_arg)
{
char *ptr = (char *)char_arg;
//some code
}
int common_func(void * arg, void (*func)(void *arg))
{
func(arg);
}
int main()
{
int a = 10;
char b = 5;
common_func((void *)&a, func_for_int);
common_func((void *)&b, func_for_char);
return 0;
}

Resources