Returning a structure array using pointers

arrays, c, data-structures, pointers, return

Solution

In your code:

person * setName() {
   person * array;
   array = malloc (2 * sizeof(person));

   array->name = strdup("Robert");
   array++;
   array->name = strdup("Jose");
   return array;
}

you allocate space for two elements in the array and set `array` to point to the first:

+-------+      +----------+
| array | ---> | array[0] |
+-------+      +----------+
               | array[1] |
               +----------+

You then increment the element pointer with `array++` and that is what gets returned to the calling function at the end. That pointer points to the second array element which is why it seems to be wrong (and why you will almost certainly crash when you try to free that memory later by the way):

+-------+      +----------+
| array | -+   | array[0] |
+-------+  |   +----------+
           +-> | array[1] |
               +----------+

What you need is:

person * setName() {
   person * array;
   array = malloc (2 * sizeof(person));

   array[0].name = strdup("Robert");
   array[1].name = strdup("Jose");
   return array;
}

as you've already pointed out. This solution does not change the `array` pointer at all. But, if you really want to use pointers, you can just reverse the actions of the `array++` with an `array--` before returning so that `array` is set back to the right value:

person * setName() {
   person * array;
   array = malloc (2 * sizeof(person));

   array->name = strdup("Robert");
   array++;
   array->name = strdup("Jose");
   array--;
   return array;
}

Or, another way, which doesn't change the original pointer, doesn't use array indexing and doesn't use a second pointer is to use pointer arithmetic. The compiler knows what type the pointer points to so can adjust the pointer correctly to find the next element (you already know that it knows how to do this since `array++` is shorthand for `array = array + 1` and that statement adjusts the value by the correct amount also):

person * setName() {
   person * array;
   array = malloc (2 * sizeof(person));

   (array+0)->name = strdup("Robert");
   (array+1)->name = strdup("Jose");
   return array;
}

Problem

``` typedef struct unit_class_struct { char *name; } person; person * setName() { person * array; array = malloc (2 * sizeof(person)); array->name = strdup("Robert"); array++; array->name = strdup("Jose"); return array; } int main() { person *array; array = setName(); printf("First name is %s\n", array[0].name); printf("Second name is %s\n", array[1].name); return 0; } ``` In this example, array[0].name returns Jose, not Robert as I expected, and array[1].name is empty. However if I use ``` person * setName() { person * array; person * array_switch; array = malloc (2 * sizeof(person)); array_switch = array; array_switch->name = strdup("Robert"); array_switch++; array_switch->name = strdup("Jose"); return array; } ``` It works as expected. array.name[0] returns Robert and array.name[1] returns Jose. Why does it require a second pointer for this example to work? Can I do it without using a second pointer AND still use pointer arithmetic? I already know this is another way to do it as well: ``` person * setName() { person * array; array = malloc (2 * sizeof(person)); array[0].name = strdup("Robert"); array[1].name = strdup("Jose"); return array; } ```

Original source