我正在检查bkhive的源代码(用C语言编写) - 一个用于从Windows NT / 2K / XP系统配置单元转储SysKey启动密钥的实用程序 - 并且想知道是否存在任何理由原作者做了:将指向struct
的指针传递给函数,然后返回相同的指针。以下是相关的源代码:
在main()
中有一个看起来像这样的电话:
struct hive h;
char *root_key;
// Do some stuff to init
_RegGetRootKey(&h, &root_key)
哪个电话:
int _RegGetRootKey(struct hive *h, char **root_key)
{
nk_hdr *n;
n = (nk_hdr*) malloc(sizeof(nk_hdr));
/* ************************************************
* RELEVANT FUNCTION CALL
* Why pass n as a parameter and use return value?
* ************************************************/
n = read_nk(n, h, 0x1020);
if (n->id == NK_ID && n->type == NK_ROOT)
{
*root_key = (char *) malloc(n->name_len + 1);
strncpy(*root_key, n->key_name, n->name_len);
(*root_key)[n->name_len] = 0;
free(n);
return 0;
}
free(n);
return -1;
}
哪个电话:
nk_hdr* read_nk(nk_hdr *nk, struct hive *h, int offset)
{
memcpy(nk, h->base + offset + 4, sizeof(nk_hdr));
nk->key_name = (h->base + offset + 4 + 76);
return nk;
}
那么,传递struct
指针然后返回它的目的是什么?该函数无法返回任何内容并在函数调用后使用n
?
答案 0 :(得分:4)
此约定的主要好处是允许更简单的函数调用串联。如果要将一个函数的返回作为参数返回到另一个函数,让它返回指针可以使您能够在一行中编写语句。因此,而不是写这样的东西:
foo(myPtr);
bar(myPtr);
你可以这样做:
bar(foo(myPtr));
您显示的特定代码不使用此代码,但这是许多C函数中使用的约定,我想这个代码的作者现在已经习惯了。
答案 1 :(得分:1)
这允许您通过引用传递对象,然后在返回时获取更新值的句柄(即指针)...它还允许您在出现错误时传回NULL,以便您知道您通过引用传入的对象的状态不再好。例如:
struct my_struct* pass_by_ref = malloc(sizeof(my_struct));
//...some more code
if (foo(pass_by_ref) == NULL)
{
free(pass_by_ref); //pass_by_ref is no longer any good ...
perror();
}
答案 2 :(得分:1)
在这种情况下,似乎没有多大用处。但总的来说,我过去做过同样的事情有两个原因:
一个是函数可能重新分配指向的项的位置,在这种情况下,返回可以是传递的相同指针,或者可以用不同的值替换它。
另一个,即使指针不会改变,它也允许函数返回立即用于访问指向项目,如somefunc(item)->member = 5;
等结构。它允许您将函数调用放入另一个需要相同指针的表达式中。
也可能只是让函数的使用与API中的其他函数一致,其中一些可能有理由这样做。