C语言 如何在修改结构体副本时不“返回局部变量地址”?

jm81lzqq  于 2023-02-15  发布在  其他
关注(0)|答案(3)|浏览(101)

我有一个结构体:

struct mystruct {
        int a;
};

如果我创建一个函数,将结构体作为参数,并尝试直接返回其地址:

struct mystruct *
modifystruct1(struct mystruct s)
{
        s.a = 5;
        return &s;
}

使用c99 -Wall -Wextra -pedantic编译将警告warning: function returns address of local variable [-Wreturn-local-addr],即I know I shouldn't do
但是,如果我将地址保存到另一个变量并尝试返回该变量,警告就会消失:

struct mystruct *
modifystruct2(struct mystruct s)
{
        struct mystruct *sptr = &s;
        sptr->a = 5;
        return sptr;
}

这样做可以吗,或者和上面的没有什么不同?(如果可以,为什么没有更多的警告?)
如果没有,我如何修改函数内的结构体副本,并安全地返回指向该结构体的指针,最好不使用malloc

7qhs6swi

7qhs6swi1#

这样做可以吗,还是和上面的没有什么不同?(如果可以,为什么没有更多的警告?)
其实也是一样的,退出函数后

struct mystruct *
modifystruct2(struct mystruct s)
{
        struct mystruct *sptr = &s;
        sptr->a = 5;
        return sptr;
}

返回的指针将是无效的,因为它指向具有自动存储持续时间的局部变量s,该局部变量在发出函数之后不活动。
编译器似乎无法确定返回的指针sptr是否指向局部对象。
请注意,函数参数没有意义,因为它在函数中会立即更改。
如果你想改变传递给函数的结构类型的对象,那么通过它喜欢的指针引用传递它

void modifystruct2(struct mystruct *s)
{
        s->a = 5;
}

如果要在函数中创建结构类型的对象并返回该对象,请按以下方式定义函数

struct mystruct modifystruct2( void )
{
        struct mystruct s = { .a = 5 };
        return s;
}
j13ufse2

j13ufse22#

1.将引用传递给结构而不是结构本身(但它将修改原始结构)

struct mystruct *
modifystruct2(struct mystruct *s)
{
        s->a = 5;
        return s;
}

1.动态分配新结构

struct mystruct *
modifystruct2(struct mystruct s)
{
        struct mystruct *sptr = malloc(sizeof(*sptr));

        if(sptr)
        {
            *sptr = s;
            sptr->a = 5;
        }
        return sptr;
}

或者不将整个结构传递给函数

struct mystruct *
modifystruct2(struct mystruct *s)
{
        struct mystruct *sptr = malloc(sizeof(*sptr));
        if(sptr)
        {
            *sptr = *s;
            sptr->a = 5;
        }
        return sptr;
}

1.按值返回结构

struct mystruct 
modifystruct2(struct mystruct s)
{
        s.a = 5;
        return s;
}
smtd7mpg

smtd7mpg3#

函数调用时:修改结构2(&s);(传递结构体地址)我会使用typedefstruct。

void modifystruct2(struct mystruct *s)
{
        s->a = 5;
        return ;
}

相关问题