0

Let's say I have a double pointer to a structure in main (i.e. an array of pointers to a struct) and I want to pass it to a function, where it will be filled. Let's say I would like to pass every "output" to the function with a "&" in front, so that it's clear which parameters are outputs. This would mean that in the function I have to deal with a triple pointer.

void fillarray(int elements, struct MyStruct *** array, int * output) {
    // fill the array
        // (see below)
    // return output
    *output = ...
}

int main() {
    // some code
    // ...

    int elements_count = 10;
    int some_int_output;

    struct MyStruct ** = malloc(elements_count * sizeof(struct MyStruct *));
    for (i = 0; i < elements_count; i++) {
        array_of_pointers[i] = malloc(sizeof(struct MyStruct));

    fillarray(elements_count, &array_of_pointers, &some_int_output);

    // some code
    // ...
    }

Now I would like to access (and fill) the array inside the function using an array notation:

for (i = 0; i < elements; i++) {
    *array[i] = ... // ONLY WORKS FOR i=0 THEN SEGFAULT
}

in analogy to how I return an integer output (*output = ...).

Instead I found that the only (?) way to access it would be:

for (i = 0; i < elements; i++) {
    *(*array + i) = ... // WORKS FOR ALL ELEMENTS
}

I think the problem has to do with which "pointer dimension" gets dereferenced first, so that *array[i] does not access the intended memory while *(*array + i) does. Using this second notation would make things more complicated and error-prone, offsetting the (supposed) advantage of having the "&" in the function call.

Does anyone have a suggestion on how to better re-write this, in order to use an array notation inside the function, while keeping the triple pointer? Is there a way to influence the "pointer dimension order"?

Thanks in advance.

PS I am aware there are (many) other ways of achieving the same result and I have successfully used a few of them. Here I was interested in knowing if the above conditions could be satisfied, while learning more about pointers.

2 Answers 2

3

No it has to do with operator precedence, this

*array[i]

is not equivalent to

(*array)[i]

but instead to

*(array[i]) => *(*(array + i))

because the array subscript operator has higher precedence than the indirection operator, so adding parentheses makes the first expression work.

Notice that for i == 0 this

*(array[i]) => *(*(array + i))

means

*(array[0]) => *(*(array + 0)) => *(*array) == *(*array + 0)

so there is no real difference which operator is evaluated first, but as i > 0 there will be a difference.

Sign up to request clarification or add additional context in comments.

1 Comment

OK, the notation (*array)[i] works indeed. I would say it is an acceptable trade-off. One would only have to remember to add parentheses when dealing with ***.
1

A solution would be:

struct MyStruct **arr = *array;

Now you can use arr like a normal double pointer.

3 Comments

Also an interesting solution, probably worth it if we do a lot of computations inside the function.
@m2oTech this solution is actually more elegant, I just didn't mention it because I was trying to explain why your code failed. But I would choos this solution, it makes it clearer,
@iharob, I think your solution more directly addresses the problem (which is indeed only a formal problem). I also find this solution elegant and I'd probably also prefer it, again less error-prone.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.