无法引用函数的结构指针,除非它之前已分配(并释放)

can't reference a struct pointer to function unless it has been previously allocated (and freed)

提问人:user2977702 提问时间:5/20/2022 最后编辑:Vlad from Moscowuser2977702 更新时间:5/20/2022 访问量:32

问:

我应该写一个很长的代码解释,但解释已经在下面的代码中,所以我想我的问题是:我如何让它工作而不必 malloc 然后释放它?或者基本上在这种情况下写这个的正确方法是什么?

#include <stdio.h>
#include <malloc.h>

struct d {
    int f;
};

struct d* rr() {
    struct d* p = malloc(sizeof (struct d*));
    p->f = 33;
    return p;
}

void rr2(struct d* p) {
    p = malloc(sizeof (struct d*));
    p->f = 22;
}



int main()
{
    //works..
    struct d* g;
    g = malloc(sizeof (struct d));
    g->f = 45;
    printf("[%i]", g->f);
    
    //works..
    g = rr();
    printf("[%i]", g->f);
    

    //below, both are same, except in this first case, g is allocated then freed..
 
    //works..
    free(g);
    rr2(g);
    printf("[%i]", g->f);
    
    //doesn't work..
    struct d *q;
    rr2(q);
    printf("[%i]", q->f);



    return 0;
}
C 指针 malloc 传递

评论

0赞 Eugene Sh. 5/20/2022
struct d gg; struct d *g = &gg;
0赞 WhozCraig 5/20/2022
公然内存泄漏的根源可能是最让你困惑的;你只是还没有意识到。rr2

答:

2赞 Vlad from Moscow 5/20/2022 #1

对于这两个功能的初学者

struct d* rr() {
    struct d* p = malloc(sizeof (struct d*));
    p->f = 33;
    return p;
}

void rr2(struct d* p) {
    p = malloc(sizeof (struct d*));
    p->f = 22;
}

有一个错别字。看来你的意思是

    struct d* p = malloc(sizeof (struct d));
                                 ^^^^^^^^

    p = malloc(sizeof (struct d));
                       ^^^^^^^^^

    struct d* p = malloc(sizeof ( *p ));
                                 ^^^^^

    p = malloc(sizeof ( *p) );
                       ^^^^^

至于这个功能

void rr2(struct d* p) {
    p = malloc(sizeof (struct d*));
    p->f = 22;
}

然后在这个电话中

struct d *q;
rr2(q);

指针按值传递给函数。因此,该函数处理指针的副本。更改函数中的副本不会反映在原始指针上。它保持不变。qqq

要使代码正常工作,您必须通过引用传递指针(间接通过指向它的指针)。在本例中,函数将如下所示

void rr2(struct d **p) {
    *p = malloc(sizeof (struct d ));
    ( *p )->f = 22;
}

并被称为

rr2( &q );

至于这个代码片段

free(g);
rr2(g);
printf("[%i]", g->f);

然后它只是调用未定义的行为,因为在此语句中

printf("[%i]", g->f);

可以访问已释放的内存。