No, you must call fds.deallocate
: it is your responsibility to do so.
The confusion here is likely because you are working with pointers-to-pointers. This can make it a bit hard to see what's going on. I'll try to break it down briefly.
In C when you want a function argument you can write back into, you must take that argument as a pointer. This is because C is pass-by-value: when you call a function you copy the argument into the callee, and any changes to it are not reflected in the caller. Consider this code:
void first(int x) {
x += 1;
}
void second(void) {
int x = 1;
first(x);
printf("%d\n", x);
}
When we execute this code we'd expect the printed result to be 1
. This is because the value of x
passed to first is an independent copy of the outer variable x
, and so cannot mutate it.
If first
wishes to write back to that value, it must accept a pointer instead, like so:
void first(int *x) {
*x += 1;
}
void second(void) {
int x = 1;
first(&x);
printf("%d\n", x);
}
Here we will expect the printed result to be 2
: we passed a pointer to our stack-allocated x
into first
, which it mutated.
So, what happens if first
wants to return us an array of int
s, instead of just a single one? An array of int
in C is represented either as int *
or int[]
(these are two equivalent ways to spell the same thing). Remember that in C to write a value of a given type into the argument requires that we accept a pointer to it, so to write an int *
back to the caller we will need to accept an argument of int **
: a pointer to a pointer to an int (or alternatively, a pointer to an array of int). That would look like this:
void first(int **x) {
*x = malloc(10);
for int(i = 0; i < 10; i++) {
(*x)[i] = i
}
}
void second(void) {
int *x = NULL;
first(&x);
for (int k = 0; k < 10; k++) {
printf("%d ", x[k]);
}
printf("\n");
}
This will print out "0 1 2 3 4 5 6 7 8 9".
This is exactly what the suggested code is doing. So, let's ask the question: who is responsible for freeing fds
? Well, in our smaller example the name of fds
is x
, but it's of the same type: int *
. Does that point to stack memory here?
No, it does not, it points to the memory allocated by malloc
. The pointer is on the stack, but the data it points to is on the heap and must be freed. Additionally, as first
has already returned, it can only be second
's responsibility to free the memory.
Again, the manual page states this explicitly:
The second argument, upon output, will point to an array of integers whose count is filled into the third argument upon success. This array represents all the sockets that launchd(8) created corresponding to the entry in the job's Sockets dictionary. Depending on the properties specified, a single Sockets entry may have multiple descriptors created for it (one for IPv4 and one for IPv6, for example). This array is allocated on the heap, and it is the caller's responsibility to call free(3) to dispose of the memory when it is no longer needed.
I omitted the free
when I updated the example: that's my mistake. You absolutely must still free that memory. We did not allocate any memory on the stack.