2013-02-07 76 views
5

为什么我不能在函数中分配一个点。正如您在以下代码中注意到的那样。函数返回后,我不能指定指向正确地址的指针p1。但是使用全局指针* p,我可以存储地址信息。C函数中的指针分配

#include <stdio.h> 
#include <stdlib.h> 

int *p = NULL; 
void test(int * pt1, int**pt2){ 
    p = (int*)malloc(sizeof(int));  
    pt1 = p; 
    *pt2 = p; 
    printf("p points to %p\n", p); 
    printf("pt1 points to %p\n", pt1); 
    printf("pt2 points to %p\n", *pt2); 
} 

int main(void) { 
    int *p1 = NULL; 
    int *p2 = NULL; 

    printf("p points to %p\n", p); 
    printf("p1 points to %p\n", p1); 
    printf("p2 points to %p\n", p2); 

    test(p1, &p2); 

    printf("p points to %p\n", p); 
    printf("p1 points to %p\n", p1); 
    printf("p2 points to %p\n", p2); 

    return 0; 
} 

OUTPUT:

p points to (nil) 
p1 points to (nil) 
p2 points to (nil) 
p points to 0x8acb008 
pt1 points to 0x8acb008 
pt2 points to 0x8acb008 
p points to 0x8acb008 
p1 points to (nil) 
p2 points to 0x8acb008 
+0

在C,一切都过去了按价值。指针也不例外。 – 2013-02-07 20:27:04

回答

4

Inside test变量pt1本身就是一个离散指针。也就是说,它不是而是仅仅是p1的别名,而是仅存在于调用生命周期中的副本。

因此,无论您对其进行的任何分配只会在该呼叫期间退出,并且不会传播到其外部。当您从test返回时,指针pt1将不复存在,并且任何更改都不会被复制回来。

除了使用指针的一个额外的“层”像你这样有pt2有时它是适当的使用与更广泛的受众,以“共享”改变返回值:

#include <stdio.h> 
#include <stdlib.h> 

int *p = NULL; 
int *test(int * pt1, int**pt2){ 
    p = (int*)malloc(sizeof(int));  
    pt1 = p; 
    *pt2 = p; 
    printf("p points to %p\n", p); 
    printf("pt1 points to %p\n", pt1); 
    printf("pt2 points to %p\n", *pt2); 
    return pt1; 
} 

int main(void) { 
    int *p1 = NULL; 
    int *p2 = NULL; 

    printf("p points to %p\n", p); 
    printf("p1 points to %p\n", p1); 
    printf("p2 points to %p\n", p2); 

    p1=test(p1, &p2); 

    printf("p points to %p\n", p); 
    printf("p1 points to %p\n", p1); 
    printf("p2 points to %p\n", p2); 

    return 0; 
} 
+0

非常感谢。我现在明白了。 – user2052197

1

您皆为传递P1由值,所以变化是唯一visable该函数的范围之内。传入一个指向该指针的指针,就像你在p2中所做的那样,并且你很好。

#include <stdio.h> 
#include <stdlib.h> 

int *p = NULL; 
void test(int **pt1, int**pt2){ 
    p = (int*)malloc(sizeof(int));  
    *pt1 = p; 
    *pt2 = p; 
    printf("p points to %p\n", p); 
    printf("pt1 points to %p\n", pt1); 
    printf("pt2 points to %p\n", *pt2); 
} 

int main(void) { 
    int *p1 = NULL; 
    int *p2 = NULL; 

    printf("p points to %p\n", p); 
    printf("p1 points to %p\n", p1); 
    printf("p2 points to %p\n", p2); 

    test(&p1, &p2); 

    printf("p points to %p\n", p); 
    printf("p1 points to %p\n", p1); 
    printf("p2 points to %p\n", p2); 

    return 0; 
} 
1

你按值传递p1,所以它不是在main功能更新。但是,您通过引用p2(请注意,您写了&p2),因此可以更改。

+0

哎呀,看起来像75inchpianist打我吧! – William