tags:

views:

5044

answers:

2

Is it possible to initialize an array of pointers to structs? Something like:

struct country_t *countries[] = {
     {"United States of America", "America"},
     {"England", "Europe"},
     {"Ethiopia", "Africa"} 
    }

I want to do that in order to get the entities in not-contiguous memory, and the pointers to them in contiguous memory... But I can't use dynamic memory, so I wonder if it is possible without it.

+20  A: 

Well, your code uses structures rather than pointers to structures. There are ways to do what you seek, including:

static struct country_t us = { "United States of America", "America" };
static struct country_t uk = { "England",                  "Europe"  };
static struct country_t et = { "Ethiopia",                 "Africa"  };

struct country_t *countries[] = { &us, &uk, &et, };

There are other ways to do it with designated initializers and compound literals in C99. Section 6.5.2.5 'Compound Literals' shows the way:

struct country_t *countries[] =
{
    &(struct country_t) { "United States of America", "America" },
    &(struct country_t) { "England",                  "Europe"  },
    &(struct country_t) { "Ethiopia",                 "Africa"  },
};

The standard illustrates pointers to structures with a function call. Be aware that not all C compilers accept C99 syntax, and these compound literals were not present in C89 (aka C90).

Edit: Upgraded to use 2-letter ISO 3166 country codes. Also made the named structures into static variables - those symbols were not visible outside the file before (because they did not exist), and now they aren't visible outside the file after, either. I debated whether to make anything const and decided not to - but using const when you can is generally a good idea. Also, in the example, there are 3 countries in 3 continents. Were you to have multiple countries in a single continent (the norm), you might want to be able to share the continent strings. However, whether you can do that safely (or at all) depends on the details of the struct country_t (which were not given), and on whether the program is allowed to update the table (which comes back to the const-ness question).

Jonathan Leffler
In your first example, you should mark all the structs as `static`: they should not need to be visible outside of the current compilation unit, and are cluttering up the linking namespace now.
ephemient
Agreed - I decided not to complicate the answer with that detail, though were I coding the solution for my own work, everything that could be static (invisible outside the file) would be.
Jonathan Leffler
A: 

This works for me:


struct country_t {
    char *fullname;
    char *shortname;
};

struct country_t countries[] = {
        {"United States of America", "America"},
        {"England", "Europe"},
        {"Ethiopia", "Africa"}
};

int main(int argc, char *argv[])
{
    return 0;
}

You could be more terse and use:


struct country_t {
    char *fullname;
    char *shortname;
} countries[] = {
        {"United States of America", "America"},
        {"England", "Europe"},
        {"Ethiopia", "Africa"}
};

int main(int argc, char *argv[])
{
    return 0;
}

Edit: I found this information at The C Book

James Fassett
The question asks for an array of pointers to structs, which means your answer misses the point, does it not?
Jonathan Leffler