I have a struct that will contain some dynamic-allocated array.
I have written the following code, and it works but I do not understand why it does work.
#include <stdio.h>
#include <stdlib.h>
struct Tray {
int *parr;
};
int allocateTray(int n, struct Tray *tray) {
tray->parr = calloc(n, sizeof(*tray->parr));
for (int i = 0; i<n; i++) {
tray->parr[i] = i+1;
}
}
int main() {
struct Tray tray = {NULL}, *ptray;
int n;
n = 5;
ptray = &tray;
allocateTray(n, ptray);
for (int i = 0; i<n; i++) {
printf("ptray->parr[%d] = %d \n", i, ptray->parr[i]);
}
return 0;
}
With a array (not inside a struct), even if I allocate arr
inside a function with argument int *arr
, it does not give main
the allocated array, and it forces one to use double pointer there.
But in this case, I just used a pointer to a struct, and it worked. I was thinking that I should use something like double pointer to a struct.
Why in this case it works only with a single pointer?
In general, whatever object a function will be expected to modify when passed via it's parameter list requires that the object's address be passed, not the object itself. To illustrate, for any type T:
For
T s
ifs
is to be changed, argument of function prototype should be;void func(T *s);
With calling example being
For
T *s
if*s
is to be changed, argument of function prototype should be;void func(T **s);
With calling example being
For
T **s
if**s
is to be changed, argument of function prototype should be;void func(T ***s);
With calling example being
And so on... (Note the apparent similarity in calling convention for each.)
Example - the following code will fail to change the value of its argument:
But this example passes address and is able to change the value:
Yes, as an argument in a function prototype that would work when needing to change the contents of memory pointed to by a pointer object.
With a pointer (to any object) that needs to be modified in a function, the same is true, its address must be passed, not the pointer itself. This then would require the argument for that function to accommodate a pointer to a pointer. A simple example using a
struct
withint
members as well as aint *
member: