简体   繁体   English

指向struct数组的指针数组

[英]Array of pointers to array of struct

I'm a C beginners and I need help. 我是C初学者,我需要帮助。 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: main中我创建了一个指向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 . 例如,当你将o (它是一个Organism[] )分配给*org[0] ,这是一个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. 但是最终会失败,因为o是一个局部变量,当函数返回时它的内存将被丢弃。

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. 清理完这些后,您需要实际为org分配一些内存,这是未初始化的。 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. 当程序退出时,如果你去malloc()路由,请务必free() org任何成员和org本身。

Note that you are defining an empty array of pointers to Organism . 请注意,您正在定义一个指向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 . 然后你访问这个数组的偏移量0(这已经是未定义的行为)和那里用作指向内存的指针的垃圾,它现在应该保存o的副本。 (Also I don't know how you managed to compile this line: *org[0] = o; ) (另外我不知道你是如何设法编译这一行的: *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 : 然后在load_organism你需要为新的Organism分配内存:

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

Or define org as 或者将org定义为

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 PS

And don't forget to free the memory after you finish using it :) 并且在使用完毕后不要忘记free内存:)

The array Organism o[3]; 阵列Organism o[3]; scope is limited to the function void load_organism() . 范围仅限于函数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; 你必须意味着org[0] = o; instead of *org[0] = o; 而不是*org[0] = o; . So, it means o and org[0] are pointer to same address. 因此,这意味着oorg[0]是指向同一地址的指针。
  • However, you must mean printf("%s", org[0]->name); 但是,你必须指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. 此外,如果你想在main()和函数中使用Organism ,你应该在你的struct中添加typedef
  • You need to initialize explicit size of the struct array or allocation 您需要初始化struct数组或分配的显式大小
  • Eventually, o is of course local variable for load_organism after function invoking it will be destroyed. 最终,在调用函数之后, o当然是load_organism局部变量。 You should use malloc() 你应该使用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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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