将结构传递给一个函数并分配它
对不起,如果这已经被问过,但我有点混淆传入和赋值给结构。将结构传递给一个函数并分配它
typedef struct test {
int x;
int y;
} test_t;
void func(test_t * test)
{
test_t second;
second.x = 2;
second.y = 3;
*test = second;
}
void main()
{
test_t first;
func(&first);
}
这是有效的吗?如果我没有记错的话,没有在func()内部结构化malloc,你不应该把func()中的指针* test指定给struct second,因为它的作用域主要在func()内部,并且一旦函数返回就会丢失。但是,在main()中打印出来的值是正确的。
有什么不同的方法来实现这个结果?这只是为了澄清一些混乱和健忘的记忆。
编辑:
的什么,我试图做的是这方面的一个更清楚的例子:
typedef struct args
{
int status;
int id;
unsigned long long start_address;
unsigned long long end_address;
unsigned long long size;
} args_t;
void ioctl_call(args_t *args)
{
args_t params;
/* get values */
ioctl(fd, cmd, params);
*args = params;
}
void main()
{
args_t args;
iotcl_call(&args);
printf("%d\n", args.id);
}
void func(test_t * test)
{
test_t second;
second.x = 2;
second.y = 3;
*test = second;
}
此代码是完全有效的,尽管低于最佳。
返回地址second
是违法的,但这不是发生了什么事。当您说*test = second
时,您将值的second
分配给解除引用的指针。编译器将生成代码以复制该结构的每个元素。
它不理想的原因是因为该副本。相反,请考虑:
void func(test_t * test)
{
test->x = 2;
test->y = 3;
}
通过这种方式,编译器将直接指定指向结构的字段。
感谢您的快速回复!出于某种原因,我过度思考,并担心第二个将会出现在堆栈中,一旦函数调用结束,这些值将变成垃圾。 – chewboy8
参数test
位于函数func
的本地,并且在函数外部更改其值不可见。
但是,您不会更改test
的值。你是解除引用它指向的内存位置并写入该位置。在这种情况下,test
包含main
中变量first
的地址。
所以,当你分配给*test
在func
你实际上是在main
分配给first
。这就是为什么你可以看到功能以外的结果。
因此,此代码将按照您的预期工作,虽然它不是最优的。正如在另一个答案中提到的,相反,将值分配给结构的本地实例,然后将其分配给解除引用的指针,您可以直接解引用指针并直接写入每个字段。
void func(test_t * test)
{
test->x = 2;
test->y = 3;
}
感谢您的解释!我正在考虑经典的“返回一个函数内部声明的数组”,以及这些值是如何变成垃圾的。这就是为什么我担心这个例子。 – chewboy8
为什么创建'second',然后踩着'test'呢?为什么不直接操作'test'呢? – tadman
@tadman这是示例代码。这并不意味着有用;它的意思是指出一些东西。 – HTNW
我的问题依然存在。在什么情况下不会直接操纵它是更好的选择? – tadman