这是关于这个问题的:为什么在这个函数中需要一个指向指针的指针来分配内存
这个问题的答案解释了为什么这不起作用:
void three(int * p)
{
p = (int *) malloc(sizeof(int));
*p = 3;
}
void main()
{
int *p = 0;
three(p);
printf("%d", *p);
}
但这是有效的:
void three(int ** p)
{
*p = (int *) malloc(sizeof(int));
**p = 3;
}
void main()
{
int *p = 0;
three(&p);
printf("%d", *p);
}
这也可以通过从函数返回指针来实现。为什么?
int* three(int * p)
{
p = (int *) malloc(sizeof(int));
*p = 3;
return p;
}
void main()
{
int *p = 0;
p = three(p);
printf("%d", *p);
}
int* three(int * p)
{
p = (int *) malloc(sizeof(int));
*p=3;
return p;
}
因为这里返回的是指针p
的副本,而该指针现在指向包含值3的有效内存。
您最初传入p
的副本作为参数,因此您不是在更改传入的副本,而是在更改副本。然后你返回副本,并分配它。
从评论来看,这是一个非常有效的观点,这也同样有效:
int* three()
{
//no need to pass anything in. Just return it.
int * p = (int *) malloc(sizeof(int));
*p=3;
return p;
}
它们完全不同(如果你真的理解第一种方法的原理,你会发现它们之间没有联系)。
通过返回,您不会试图从函数内部修改已经存在的指针。您只是返回一个新指针,并在外部指定其值。
将其视为范围问题。
在main()
中,您有一个指针p
。
int *p = 0;
main中的p
设置为NULL。当你调用传递它的三个函数p:时
three(p);
您正在传递一个指向NULL的指针。它发生的事情不在main()
的范围内。main()
不知道,也不在乎会发生什么。main()
只关心其p
的副本,此时该副本仍设置为NULL。除非我在main()
的范围内重新分配p
(包括切换p
的地址),否则p
仍然只是一个指向NULL的指针。
如果我给你这个代码:
void main()
{
int *p = 0;
funcX(p);
printf("%d",*p);
}
您可以明确地告诉我将要发生什么(Segmentation fault),而不知道funcX()
会做什么,因为我们将指针的副本传递给该函数,但副本不会影响原始函数。
但如果我给你这个代码:
void main()
{
int *p = 0;
funcX(&p);
printf("%d",*p);
}
除非你知道funcX()
在做什么,否则你不能告诉我会发生什么。
这有道理吗?