[C] multi-dimensional array allocation and using them in functions

In summary, the conversation discussed the use of pointers in C programming, particularly when allocating and using multidimensional arrays. The code presented a simple problem of allocating a two-dimensional array, printing its components, reallocating it, and subtracting its rows by 2. The code also showed the use of the write function to print the components of the array. The conversation then delved into the difference between *a and **a, with the conclusion that **a is necessary for multidimensional arrays. The use of malloc and realloc was also mentioned as alternative ways to allocate arrays. Finally, the conversation touched on the proper syntax for adding or subtracting rows in an array and the importance of using parentheses in pointer declarations.
  • #1
Fb.Researcher
9
0
I am a beginer in C programming,so I have just became familiar with pointers.The problem I am writing a program to solve requires me to allocate a multidimensional array, reallocate it and use it in some functions.The simplest problem would be:allocating a two dimensional array, ask a function to print it's components, reallocate it and subtract it's rows by 2 and again give it to the function to print it's components.My code is:
main(){
int **a,i,j;
a=calloc(6,sizeof(int *));
for(i=0;i<6;i++)
a=calloc(6,sizeof(int));
for(i=0;i<6;i++)
for(j=0;j<6;j++)
a[j]=i*j;
write(a);
return (0);
}
write is the function that should print the components:
void write(int a[6][6])
{ int i,j;
for(i=0;i<6;i++)
{for(j=0;j<6;j++)
printf("%4i",**a[j]);
printf("\n");
}
}
Now here are my questions:
Why the array pointer should be **a and not *a?I have this syntax by searching through the internet but there was no other explanation about it.The only thing I could find in books was that a pointer is defined by a statement like :
int *a;
another problem is using the allocated array in a function.You see compiling the code gives me the following error(Itried to solve it by defining the right kind of argument but I think the failure is due to my lacking of knowledge in pointers.I know about the calling by reference and value)

c:24:2: warning: passing argument 1 of ‘write’ from incompatible pointer type [enabled by default]
note: expected ‘int (*)[6]’ but argument is of type ‘int **’

The program is not compiled.My compiler is gcc.Please help me!
 
Technology news on Phys.org
  • #2


Fb.Researcher said:
void write(int a[6][6])
That statement should be:

void write(int **a)

a[6][6] is a 2 dimensional matrix, all integers (no pointers). int **a or int*a[...] is a pointer to pointer to an integer, or an array of pointers to integers, or an array or pointers to arrays of integers (which is what your program is using).

Fb.Researcher said:
printf("%4i",**a[j]);

That statement should be:

printf("%4i",a[j]);

You did it correctly when you used:

a[j]=i*j;

Also use the tags [ code ] and [ /code ] (without the spaces) before and after your code to see the indentation of your code. If your code has tabs, they default to 8 spaces at this forum, so you may want to convert tabs to spaces in your source code before posting here.
 
Last edited:
  • #3
Thank you for your explanation.So if I have truly understood for every dimension of the array I need a loop that allocate an extra dimension and an array of pointers to another array that could be another array of pointers or in two dimensions an array of integers. For example in three dimensions I need ***a.Am I right?
Now I have another question. Is there any other way to allocate an array? For example by using malloc function?
And please tell me how can I add or subract rows by n?I know that I should use realloc.but for a one dimensional array the syntax I have used seemed to be wrong.I used:
Code:
 int *ap;
ap=calloc(6,sizeof(int)); 
         //changing the valus of array's members 
ap=realloc(ap,sizeof(int)*2);
         //rest of the code and printing the results
free(ap);
it seems that using wrong syntaxes gives no errors but causes strange results.
 
  • #4
Fb.Researcher said:
So if I have truly understood for every dimension of the array I need a loop that allocate an extra dimension and an array of pointers to another array that could be another array of pointers or in two dimensions an array of integers. For example in three dimensions I need ***a.
Using an array of pointers for a matrix isn't required if the number of columns are fixed in size (at compile time). You can use a pointer to a matrix of integers instead. Note, without the parenthesis around *pmi , you'd have a matrix of pointers to integers (and the first dimension would have to be specified).

Code:
int i, j;
int (*pmi)[][6];        /* ptr to matrix with 6 columns per row */

    pmi = (void *) malloc(4*6*sizeof(int));

    for(i = 0; i < 4; i++){
        for(j = 0; j < 6; j++){
            (*pmi)[i][j] = i*j;
        }
    }

/* ... */

    free(pmatrix);

You could also use a pointer to an array of integers, then index the pointer to access a marix of integers:

Code:
int i, j;
int (*pai)[6];          /* ptr to array of 6 integers or 1st row of matrix */

    pai = malloc(4*6*sizeof(int));
    for(i = 0; i < 4; i++){
        for(j = 0; j < 6; j++){
            pai[i][j] = i*j;}}

/* ... */

    free(pai);

The advantage of using an array of pointers is that the number of columns doesn't have to be fixed at compile time. For a 3d tensor, you would use an array of pointers to arrays of pointers to arrays of integers. If the size of the last two dimensions is known at compile time, then you can use a ptr to an array of matrices or a ptr to the 1st matrix in an array of matrices, similar to the code above.

Fb.Researcher said:
realloc
It might be more readable to use malloc and realloc, since the size parameter for both is specified in bytes:

Code:
int i;
int *pi;                /* ptr to integer or 1st integer of array */

    pi = malloc(4*sizeof(int));
    for(i = 0; i < 4; i++)
        pi[i] = i;

    pi = realloc(pi, 8 * sizeof(int));
    for(i = 4; i < 8; i++)
        pi[i] = i;

/* ... */

    free(pi);
 
Last edited:
  • #5

Hello,

First of all, congratulations on becoming familiar with pointers and attempting to use them in your code. Pointers can be a tricky concept to grasp at first, but once you understand them, they can be very useful in programming.

To answer your first question, the array pointer should be **a because you are allocating a two-dimensional array. In C, a two-dimensional array is essentially an array of arrays. So, **a represents a pointer to an array of pointers, where each pointer points to an array of integers. This is why you need **a to correctly allocate and access the elements of your 2D array.

As for your second question, the reason you are getting an error when passing the array to the write() function is because the function is expecting an argument of type int (*)[6], which is a pointer to an array of 6 integers. However, you are passing it a pointer to a pointer to an integer, or int **. To fix this, you can change the function declaration to accept an int ** argument, or you can change the type of the array to int (*)[6] when calling the function.

Here is an example of how you can modify your code to make it work:

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

void write(int **a);

int main(){
int **a,i,j;
a=calloc(6,sizeof(int *));
for(i=0;i<6;i++)
a=calloc(6,sizeof(int));
for(i=0;i<6;i++)
for(j=0;j<6;j++)
a[j]=i*j;
write(a); //changed the argument to int **a
return (0);
}

void write(int **a)
{
int i,j;
for(i=0;i<6;i++)
{
for(j=0;j<6;j++)
printf("%4i",a[j]); //removed the extra * from **a[j]
printf("\n");
}
}

I hope this helps clarify things for you. Keep practicing and learning about pointers, and you will become more comfortable using them in your code. Best of luck!
 

FAQ: [C] multi-dimensional array allocation and using them in functions

How do I allocate memory for a multi-dimensional array in C?

To allocate memory for a multi-dimensional array in C, you can use the malloc() function. For example, if you want to allocate a 2D array with 3 rows and 4 columns, you can use malloc(3 * sizeof(int*)) to allocate memory for the rows, and then use a loop to allocate memory for each column in each row using malloc(4 * sizeof(int)).

Can I pass a multi-dimensional array to a function in C?

Yes, you can pass a multi-dimensional array to a function in C. When passing a multi-dimensional array to a function, you need to specify the size of the array for each dimension except the first one. This is because the first dimension is automatically determined by the compiler based on the number of elements in the array.

How do I access elements in a multi-dimensional array in C?

To access elements in a multi-dimensional array in C, you can use the square bracket notation. For example, if you have a 2D array called myArray, you can access the element in the first row and second column by using myArray[0][1]. Keep in mind that the first index represents the row and the second index represents the column.

What is the difference between a 2D array and an array of pointers in C?

A 2D array in C is a contiguous block of memory that stores elements in a matrix-like fashion. An array of pointers, on the other hand, is an array where each element is a pointer to another array. This means that an array of pointers can be used to create a jagged array, where each row can have a different number of columns.

How can I free the memory allocated to a multi-dimensional array in C?

To free the memory allocated to a multi-dimensional array in C, you can use the free() function. However, you need to be careful when freeing a multi-dimensional array because you need to free each row individually before freeing the entire array. This is because the rows are allocated separately using malloc(). If you try to free the entire array at once, you will end up with a memory leak.

Similar threads

Replies
6
Views
2K
Replies
25
Views
2K
Replies
22
Views
3K
Replies
4
Views
2K
Replies
23
Views
2K
Back
Top