【问题标题】:Pass GList by reference通过引用传递 GList
【发布时间】:2013-11-11 16:21:10
【问题描述】:

我正在尝试将实体寄存器维护为链接列表,其中包含一组接受对列表的引用并对其进行修改的函数。我已经在结构内部使用了 GLists 的这种策略,效果非常好,但为此我不需要容器结构。我想要做的是:

// Creates a new entity and appends it to the global entity index.
// Returns ID of the newly created entity, not a pointer to it.
int anne_entity_create(char entity_name[], char entity_type[], GList *Entities) {

    ANNE_ENTITY *newEntity = malloc(sizeof(ANNE_ENTITY));
    ANNE_ENTITY_RECORD *newEntityRecord = malloc(sizeof(ANNE_ENTITY_RECORD));

    newEntity->id = anne_entity_get_next_id(Entities);
    sprintf(newEntity->name, "%s", entity_name);
    sprintf(newEntityRecord->name, "%s", entity_name);

    newEntityRecord->entity = newEntity;

    Entities = g_list_append(Entities, newEntityRecord);

    printf("Index length: %i\n", g_list_length(Entities));

    return newEntity->id;
}

//Entity system setup
GList* Entities = NULL;
printf("Entity ID: %i\n", anne_entity_create("UNO", "PC", Entities));
printf("Entity ID: %i\n", anne_entity_create("DOS", "PC", Entities));
printf("Index length: %i\n", g_list_length(Entities));

anne_entity_create() 内部的g_list_length() 返回 1,而在外部执行的相同函数返回 0。很明显,GList 在传递给anne_entity_create() 时正在被复制,但我不知道为什么 - 和通过 &reference 传递它应该是不必要的,因为(据我所知)使用GList* Foo; 语法创建一个 GList 无论如何都会产生一个指针。

我确定我完全误解了我正在做的事情,但我已经为此研究了好几个小时。

【问题讨论】:

    标签: c linked-list glib


    【解决方案1】:

    您将单个指针传递给您的函数,这意味着您可以修改指针指向的内容,在本例中为 NULL,并且您使用本地指针(范围为您的函数 anne_entity_create)指向NULL,然后指向那个指针,你“附加”你的列表,这使它只能在本地访问。

    因此您需要使用双重间接:将指向表头指针的指针传递给您的函数,然后对其进行操作,因此您正在更改列表的实际头,而不是传递地址的副本列表的头部。希望您能理解,请随时提出更多问题。

    GList *Entities = NULL;
    anne_entity_create("UNO", "PC", &Entities) //Inside your function pass *Entities to append
    
    // Creates a new entity and appends it to the global entity index.
    // Returns ID of the newly created entity, not a pointer to it.
    int anne_entity_create(char entity_name[], char entity_type[], GList **Entities) {
    
        ANNE_ENTITY *newEntity = malloc(sizeof(ANNE_ENTITY));
        ANNE_ENTITY_RECORD *newEntityRecord = malloc(sizeof(ANNE_ENTITY_RECORD));
    
        newEntity->id = anne_entity_get_next_id(*Entities);
        sprintf(newEntity->name, "%s", entity_name);
        sprintf(newEntityRecord->name, "%s", entity_name);
    
        newEntityRecord->entity = newEntity;
    
        *Entities = g_list_append(*Entities, newEntityRecord);
    
        printf("Index length: %i\n", g_list_length(*Entities));
    
        return newEntity->id;
    }
    

    【讨论】:

    • GList ** Entities; *Entities = NULL; 段错误。调查了一下,但我只是有点理解你的建议。
    • 这个答案的原理是正确的,但是给出的代码确实会出现段错误。我继续编辑它;-)
    • 是的,我搞砸了,它的segfaults,因为双指针,没有初始化,因为土豆编辑,你应该传递指针的引用,或者分配一个双指针,但是土豆提供的解决方案更好.
    • 为了进步,昨晚我合理化了将我的列表放入父结构中,理由是要求可以使附加数据成为传递的好主意。但是,为了自我充实,我仍然会从 git 中复制前缀代码并尝试您的解决方案。 :)
    猜你喜欢
    • 1970-01-01
    • 2015-01-12
    • 2013-09-10
    • 2020-04-01
    • 1970-01-01
    • 2011-06-28
    • 2015-07-22
    • 2015-05-02
    • 2012-03-13
    相关资源
    最近更新 更多