DJames DJames - 2 months ago 15
C Question

How do I allocate memory, assign values, and return it to the calling function?

Answers to this question describe how to allocate memory and return it to the calling function. An example was given:

void someFunction (int **data) {
*data = malloc (sizeof (int));
}

void useData (int *data) {
printf ("%p", data);
}

int main () {
int *data = NULL;

someFunction (&data);

useData (data);

return 0;
}


I would also like to assign values before returning to the calling function. However, when I try (for example):

void someFunction (int **data) {
*data = malloc (2 * sizeof (int));
*data[0] = 1;
*data[1] = 1;
}

void useData (int *data) {
printf ("%p", data);
}

int main () {
int *data = NULL;

someFunction (&data);

useData (data);

return 0;
}


I receive a segmentation fault. Any help is appreciated.

Answer Source

Your problem lies with the statement:

*data[0] = 1;

Because of the way precedence works (a), this is actually equivalent to:

*(data[0]) = 1;

rather than, as you expected:

(*data)[0] = 1;

The former variant actually tries to dereference a not-yet-assigned (arbitrary) value, which is what's causing your crash. You should use the latter form to be more explicit.

In any case, it's always a good idea to check any calls that can fail so as to not cause problems later on based on incorrect assumptions. You may also want to consider what will happen if you call the function twice (or more) - it will currently result in a memory leak since the old memory is never freed.

With those points in mind, I would be modifying your function slightly as follows:

void someFunction (int **data) {
    // Release old memory if any (freeing NULL is fine).

    free (*data);

    // Allocate new memory and initialise only if it worked.

    *data = malloc (2 * sizeof (int));
    if (*data != NULL) {
        (*data)[0] = 1;
        (*data)[1] = 1;
    }
}

(a) Precedence is dictated by the order of appearance of expression types in the standard. For example, C11 6.5 Expressions states:

The syntax specifies the precedence of operators in the evaluation of an expression, which is the same as the order of the major subclauses of this subclause, highest precedence first.

And, since array subscripting appears in 6.5.2.1 compared to indirection in 6.5.3.2, the former will happen first.