boltup_im_coding
boltup_im_coding

Reputation: 6665

How do you return a struct from an array within a function? (pointers)

Consider this code:

typedef struct fruits_s
{
    char* key;
    char value;
} fruits_t;

static fruits_t fruit_array[] = {
{ "Apple", 1 },
{ "Banana", 2 },
{ "Grape", 3 },
{ "Orange", 4 } };

static fruits_t* getFruitFromValue(char value)
{
    int i;
    for (i = 0; i < sizeof(fruit_array)/sizeof(fruit_array[0]); i++){
        if (value == fruit_array[i].value){
            return fruit_array[i];
        }
    }
}

I am new to C and am still learning when pointers are necessary/used. I come spoiled from a Java background. So, in the above code, what I'm confused of is should the function return a pointer fruits_t*? Or something else? When I do fruit_array[i] is that a pointer to my struct, or the struct itself?

That being said, later in my code when I want to use the function, is it this:

 fruits_t* temp = getFruitFromValue(1);

or

 fruits_t temp = getFruitFromValue(1);

or

 fruits_t temp = &getFruitFromValue(1);

Upvotes: 4

Views: 158

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 753765

The function could return either — your choice. You've said you'll return a pointer; that's OK as long as you do.

When you write:

static fruits_t *getFruitFromValue(char value)
{
    int i;
    for (i = 0; i < sizeof(fruit_array)/sizeof(fruit_array[0]); i++){
        if (value == fruit_array[i].value){
            return fruit_array[i];
        }
    }
}

There are several problems:

  1. fruit_array[i] is a structure, not a pointer. Use return &fruit_array[i];.
  2. If the loop exits, you don't return a value from the function at all.

Fixing those leads to:

static fruits_t *getFruitFromValue(char value)
{
    int i;
    for (i = 0; i < sizeof(fruit_array)/sizeof(fruit_array[0]); i++)
    {
        if (value == fruit_array[i].value)
            return &fruit_array[i];
    }
    return NULL;
}

This is OK because the pointer you return is to static data that will outlive the function. If you tried to return a pointer to non-static data, you would (probably) have a bug on your hands, unless you used dynamic memory allocation (via malloc() et al).

You could also return the structure; handling the error return becomes harder. If you've got C99, you can use a 'compound literal':

static fruits_t getFruitFromValue(char value)
{
    int i;
    for (i = 0; i < sizeof(fruit_array)/sizeof(fruit_array[0]); i++)
    {
        if (value == fruit_array[i].value)
            return fruit_array[i];
    }
    return (fruits_t){ .key = "", .value = 0 };
}

Upvotes: 4

Related Questions