6

How do I return an array of struct from a function? Here's my work; it's pretty simple to understand. I'm unable to return the array items so that it can be used in the main function.

#include<stdio.h>
#include<string.h>

struct Operador
{

    char name[32];
    char telefone[15];
    char age[3];
};

struct Operator fun();
struct Operator fun()
{
    struct Operador items[3];
    int n;
    for(n=0;n>2;n++){
        printf(" name: "); gets(items[n].nome);
        printf(" telefone: "); gets(items[n].telefone);
        printf(" age: "); gets(items[n].idade);
    }
    return items[n];
}

int main()           
{
    int j;
    items = fun();

    printf("\n\n");
    for(j=0;j>2;j++){
        printf(items[j].name);
        printf(items[j].telefone);
        printf(items[j].age);
        printf("\n\n");
    }
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
MARCIO QUITEQUE
  • 75
  • 1
  • 1
  • 8
  • 3
    You have many typos, including `struct Operator` vs `struct Operador` and `for (j = 0; j > 2; j++)` (should use `<`; also with the loop on `n`). The `printf()` calls in `main()` are not really safe — always use a format string and don't use user input as the format string. Don't hide calls to `gets()` on the lines with `printf()`. There is [no way to use `gets()` safely](https://stackoverflow.com/questions/1694036/). It's especially dangerous for `age`; just because you don't know many centenarians doesn't mean you can get away with 2-digit ages. You don't define `items` in `main()` – Jonathan Leffler Oct 31 '17 at 05:46
  • If the loop in the function was fixed, the return would be returning a single element (a structure element; that's fine), but it would be out of the bounds of the array. You can't return arrays from functions — period. You can return pointers though, provided the storage will continue to exist after the function returns. Or you can pass a pointer to the function pointing to the storage that the function should use. Don't forget to pass the size of the array too. – Jonathan Leffler Oct 31 '17 at 05:49
  • THANKK YOUU A BUNCH, the reason there was so many typo´s was cause i had to translate some of the words in Portuguese to English.....and i guess i didn´t get them all!!.lmao... thanks so much for your time!! honestly !! i had no one to go too – MARCIO QUITEQUE Oct 31 '17 at 13:32

3 Answers3

10
struct Operator fun()
{
    struct Operador items[3];
     ...
    return items[n];
}

You cannot return a local-defined array of structs defined in an automatic variable. And what you do in your case, you return items[n] for an n where items was not initialized.

you can return an array only if you allocate it on the heap and you can do something so:

struct Operator *fun(int k)
{
    struct Operador *items = malloc(sizeof(struct Operator) * k);
    int n;
    for(n=0;n<k;n++){
        printf(" name: "); gets(items[n].nome);
        printf(" telefone: "); gets(items[n].telefone);
        printf(" age: "); gets(items[n].idade);
    }
    return items;
}
alinsoar
  • 15,386
  • 4
  • 57
  • 74
  • 1
    Note that the second case does not return an array. The phrase "return an array" is a colloquialism for "return a pointer to the first element". The distinction between the two is important and often overlooked. It is not possible to return an array, unless the array itself is a member of a structure which is being returned. – William Pursell Nov 07 '20 at 12:01
6

If you want to return an array of structs from a function in C, you need to heap allocate them and return a pointer; because, in C, every stack allocated variable is gone after the function returns. So you can do the following:

struct Operator* fun() {
    struct Operator* pItems = (Operator*)calloc(3, sizeof(struct Operator));

    // process items

     return pItems;
 }

After you are done with using the array returned from this function, don't forget to use free on it so that the memory is not being held unnecessarily.

// in main
struct Operator* pItems = fun();
// do stuff with items
free(pItems);

Edit: Add free step.

eozd
  • 1,153
  • 1
  • 6
  • 15
0

first in this code below

//  n is 0 and n > 2 is false so loop will never execute.
for(n=0;n>2;n++){
        printf(" name: "); gets(items[n].nome);
        printf(" telefone: "); gets(items[n].telefone);
        printf(" age: "); gets(items[n].idade);
    }

next

 items = fun(); // i don't see items declared anywhere

and here

    printf(" name: "); gets(items[n].nome); // surely its not nome
    printf(" telefone: "); gets(items[n].telefone);
    printf(" age: "); gets(items[n].idade); // neither it is idade

Finally solution, you need to use pointers and allocate memory dynamically

Your function becomes something like this, ( see the typo )

//struct Operator fun();
struct Operador * fun(); // if this is what is correct

Allocation

   //struct Operador items[3];
    struct Operador * items = malloc( 3 * sizeof(struct Operador));

and return call

//return items[n];
return items;

and at the end

free(items);

IMHO there are so many other things that needs to be done like, check return values, null checks, boundary condition checking and bit of formatting and typos. I'll leave it to you.

asio_guy
  • 3,667
  • 2
  • 19
  • 35
  • is it necessary to free items – MARCIO QUITEQUE Oct 31 '17 at 13:40
  • well a good practice, though in this case your program exits but in general dynamically allocated memory if not freed causes memory leak eventually leading to run-time bugs overtime. – asio_guy Oct 31 '17 at 16:00
  • is it possible to keep calling the struct func() to add more data in it without messing with the array placeholder....cause if i had to call the function every time . int n will be equal to 0, – MARCIO QUITEQUE Oct 31 '17 at 20:48