简体   繁体   中英

Array of pointers to array of struct

I'm a C beginners and I need help. I've a struct like this the following one:

    struct {
        char*   name;
        int     level;
        int     spring_prob;
        int     population;
    } Organism;

Organism with the same level have to be grouped into the same array to create a situation like that:

    +++++         +++++++++++++++++++++++++++
    | 0 |  -->    | organism_0 | organism_1 |
    +++++         ++++++++++++++++++++++++++++++++++++++++
    | 1 |         | organism_2 | organism_3 | organism_4 |
    +++++         ++++++++++++++++++++++++++++++++++++++++
    | 2 |         | organism_5 |
    +++++         ++++++++++++++
     org

In main i created an array to pointer to array of struct:

    int main {
        ...
        Organism *org[];
        load_organism(org);
        show(org);
        return 0;
    }
    void load_organism (Organism *org[]){
        Organism o[3];
        o[0].name = "abc";
        o[0].level = 0;
        o[0].spring_prob = 25;
        o[0].population = 300;

        o[1].name = "def";
        o[1].level = 0;
        o[1].spring_prob = 25;
        o[1].population = 20;

        o[2].name = "ebs";
        o[2].level = 0;
        o[2].spring_prob = 25;
        o[2].population = 20;

        *org[0] = o;
    }
    void show (Organism* org[]) {
        print("%s", org[0][0].name);
    }

It crashes when i try to print the name of the first organism. I hope you could help me finding the error. Thanks in advance.

You should be seeing a number of compiler warnings with that code.

For example, when you assign o (which is an Organism[] ) to *org[0] , which is an Organism . Heed those warnings.

In this case, you mean to say:

org[0] = o;

But that will fail eventually, since o is a local variable, and its memory will be discarded when the function returns.

Create it, instead, as:

Organism *o = malloc(3 * sizeof(Organism));

Once those are cleaned up, you'll need to actually allocate some memory to org , which is uninitialized. Bad news when you assign to its members.

Either give the array a specific size like so:

Organism *org[10];

or allocate it as above:

Organism **org = malloc(10 * sizeof(Organism *));

or

Organism **org = calloc(10, sizeof(Organism *));

When the program exits, be sure to free() any members of org , and org itself if you go the malloc() route.

Note that you are defining an empty array of pointers to Organism . Then you access offset 0 of this array (which is already undefined behavior) and the garbage that is there used as a pointer to a memory which should now hold the copy of o . (Also I don't know how you managed to compile this line: *org[0] = o; )

Agree with me that even you would segfault at some moment :).

Either define a fixed size of this array:

#define NUM_OF_ORGANISMS 10

int main()
{
    Organism *org[NUM_OF_ORGANISMS];
    ....
}

and then in load_organism you need actually to allocate the memory for the new Organism :

org[0] = malloc(sizeof(Organism));
*org[0] = o[0];

Or define org as

Organism** org;

And then dynamically allocate the size of the array and each entry of it.

org = malloc(sizeof(Organism*)*NUM_OF_ORGANISMS);
....
org[i] = malloc(sizeof(Organism));
...
// now you can access it
*org[i] = ...

PS

And don't forget to free the memory after you finish using it :)

The array Organism o[3]; scope is limited to the function void load_organism() .

You are trying to access it after the function has exited. This invokes undefined behavior.

  • You must mean that org[0] = o; instead of *org[0] = o; . So, it means o and org[0] are pointer to same address.
  • However, you must mean printf("%s", org[0]->name); instead of
    print("%s", org[0][0].name); .
  • Besides, If you want to use Organism like in main() and functions, you should add typedef to your struct.
  • You need to initialize explicit size of the struct array or allocation
  • Eventually, o is of course local variable for load_organism after function invoking it will be destroyed. You should use malloc()

Fixed code:

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    char*   name;
    int     level;
    int     spring_prob;
    int     population;
} Organism;

void load_organism (Organism *org[]){
    Organism *o = malloc(3 * sizeof(Organism));
    o[0].name = "abc";
    o[0].level = 0;
    o[0].spring_prob = 25;
    o[0].population = 300;

    o[1].name = "def";
    o[1].level = 0;
    o[1].spring_prob = 25;
    o[1].population = 20;

    o[2].name = "qwe";
    o[2].level = 0;
    o[2].spring_prob = 25;
    o[2].population = 20;

    org[0] = o;
}
void show (Organism* org[]) {
    printf("%s", org[0]->name);
}

int main()
{
    Organism *org[3];
    load_organism(org);
    show(org);
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM