我在代码的几乎每个部分都看到了以下初始化本地指针的方法。我想了解这样做的原因和复杂性。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void initialize_p(char **p)
{
char *p_local = NULL;
p_local=malloc(6);
strcpy(p_local,"sandy");
*p = p_local;
}
int main(void)
{
char *p = NULL;
initialize_p(&p);
printf("Name : %s\n",p);
return 0;
}
就是这样,我在这里用简单的字符串显示。在我的实际代码中,它是使用结构完成的。
我有点理解上面的逻辑而且我没有。请明确上述实施方式所涉及的概念。另外,如果还有其他更好的方法可以让我知道。
请启发.. :)
答案 0 :(得分:4)
我可能会返回新分配的字符串,而不是将指针作为参数传递给指针:
char *initialize(void) {
char *init = "sandy";
char *ret = malloc(sizeof(init)+1);
if (ret != NULL)
strcpy(ret, init);
return ret;
}
int main() {
char *p = initialize();
printf("Name: %s\n", p);
free(p);
return 0;
}
答案 1 :(得分:0)
这是一个超出参数。该函数为您生成结果,并将其保存到您传递的参数中。当结果的大小可能不同,或者参数的类型是不透明时,通常会使用此方法。
就我个人而言,我认为当需要动态分配时,返回结果会更清晰,并且不易出错(如JerryCoffin的答案+1中所示)。
当不需要动态分配时,如果它不是很小的话,则通过引用传递它(作为非const参数):
struct t_struct { int a[100]; };
void InitStruct(struct t_struct* pStruct) {
pStruct->a[0] = 11;
...
}
struct t_struct s;
void InitStruct(&s);
如果它很小,你可以考虑按值返回。
答案 2 :(得分:0)
在initialize_p中,分配了一块内存,并将一些字符串复制到内存中。为了让初始化器的调用者获得这个新的内存块的地址,指针p的地址被传递给initialize_p:
char **p
+---+---+---+---+---+----+
*p -> | s | a | n | d | y | \0 |
+---+---+---+---+---+----+
如果只传递* p,则在函数内设置指针将等效于:
void foo(int a)
{
a=3;
...
}
更好的方法是使用strdup,它与你在函数中做同样的事情
char* initialize_p()
{
return strdup("sandy");
}
还要确保释放返回的字符串以避免内存泄漏。
答案 3 :(得分:0)
我建议您创建分配和释放功能对
char *createP()
{
char *p = NULL;
p=malloc(6);
strcpy(p,"sandy");
return p;
}
void freeP(char *p)
{
if (p) free(p);
}
int main(void)
{
char *p = createP();
printf("Name : %s\n",p);
freeP(p);
return 0;
}
答案 4 :(得分:0)
清除这个概念?好吧,在这么简单的情况下,我没有看到使用byref输出参数操作的重点 - 对我来说,面向对象的结构构造函数如果它们的工作方式更容易理解:
struct foo *bar = myobj_new(); // uses malloc and returns a pointer
// do something with bar
myobj_destroy(bar); // uses free
有些人认为这个设计很好,因为这个函数的返回值可以用作错误/成功代码(你见过SQLite3吗?),但我不同意。我认为函数的主要,最重要的结果应该是返回值,而不是一些辅助内容。 (我倾向于编写通过返回NULL并设置byref传递的错误代码来指示失败的库。)
我能想到的唯一有效场景是传递这样的参数更合乎逻辑或更对称。例如,想象一个非常奇怪的排序函数,它类似于C stdlib函数qsort()
,但需要它的比较函数本身在需要时交换两个元素。比较函数显然需要通过参数访问它的两个参数来交换它们,但是为了优化算法,将原始遇到的顺序返回给调用者排序函数也是有用的。所以这个比较函数可能是这样的:
int compare(void *a, void *b)
{
int x = *(int *)a;
int y = *(int *)b;
if (x > y)
{
*(int *)a = y;
*(int *)b = x;
return +1;
} else if (x < x) {
return -1;
}
return 0;
}
嗯,差不多就是我的意见......