C 从函数返回指针

C 从函数返回指针,c,memory-management,malloc,C,Memory Management,Malloc,这是关于这个问题: 问题的答案解释了为什么这不起作用: 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)

这是关于这个问题:

问题的答案解释了为什么这不起作用:

    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);
    }
因为这里返回的是指针
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
设置为空。当调用传递它的三个函数p时:

three(p);
您正在传递一个指向NULL的指针。它发生的事情超出了
main()
的范围
main()
不知道,也不关心发生了什么
main()
只关心其
p
的副本,此时该副本仍设置为NULL。 除非我在
main()
(包括传递
p
的地址)的范围内重新分配
p
p
仍然只是指向NULL的指针

如果我给你这个代码:

void main()     
{
     int *p = 0;
     funcX(p);
     printf("%d",*p);     
} 
void main()     
{
     int *p = 0;
     funcX(&p);
     printf("%d",*p);     
} 
您可以明确地告诉我将要发生什么(分段错误),而不知道
funcX()
会做什么,因为我们正在将指针的副本传递到此函数,但副本不会影响原始指针

但如果我给你这个密码:

void main()     
{
     int *p = 0;
     funcX(p);
     printf("%d",*p);     
} 
void main()     
{
     int *p = 0;
     funcX(&p);
     printf("%d",*p);     
} 
除非您知道
funcX()
正在做什么,否则无法告诉我将发生什么


有意义吗?

在这里传递指针是没有意义的,因为malloc无论如何都会覆盖它。@KingsIndian:我想说,相反,在这里分配内存是没有意义的,因为指针无论如何都会被传递P@netcoder:这取决于调用方是否需要分配。@TonyTheLion:Right。这是所有权的问题。我很少返回已分配的指针,我更喜欢让调用者分配并释放所需的内存。@netcoder无论所有权如何,我以前的命令仍然有效。i、 e.当您要覆盖指针时,您不必传递它:)