C中的双指针及其作用域

C中的双指针及其作用域,c,pointers,C,Pointers,我有以下代码: void alloc2(int** p) { *p = (int*)malloc(sizeof(int)); **p = 10; } void alloc1(int* p) { p = (int*)malloc(sizeof(int)); *p = 10; } int main(){ int *p; alloc1(p); //printf("%d ",*p);//value is undefined alloc2(&p)

我有以下代码:

void alloc2(int** p) {
   *p = (int*)malloc(sizeof(int));
   **p = 10;
}

void alloc1(int* p) {
   p = (int*)malloc(sizeof(int));
   *p = 10;
}

int main(){
   int *p;
   alloc1(p);
   //printf("%d ",*p);//value is undefined
   alloc2(&p);
   printf("%d ",*p);//will print 10
   free(p);
   return 0;
}
所以,我知道alloc1只是生成一个本地副本,所以它不会影响函数外部作为参数给出的指针

但是alloc2发生了什么

tl;博士

为什么这
alloc1(&p)不起作用

更新

我想我回答了我的问题。关键的一点是
&
使您成为一个指针,然后
a
被构建为一个双指针bei去引用一次。然后双指针指向给定的地址
malloc
。最后,地址中填充了
10

alloc1(&p)
可以工作,但您无法解除双指针的防护,因为它只使用一个指针


感谢大家,它没有变成双指针,在
alloc2()
中,您正在传递一个包含
main()
p
地址的指针。取消引用时,实际上是在修改存储在
main()
p
中的地址。这就是它起作用的原因

由于中没有按引用传递,因此修改函数内参数的唯一方法是通过传递带有其地址的指针,例如,如果必须将整数传递给函数且函数需要修改,则使用
&
运算符的地址创建指针,并将该指针传递给函数,范例

void
modify(int *pointer)
{
    *pointer += 1;
}

int
main(void)
{
    int value;
    value = 0;

    modify(&value);
    printf("%d\n", value);

    modify(&value);
    printf("%d\n", value);
}
将输出

1
2
双指针是指向指针的指针,因此您正在从
main()
中的
p
创建一个指针,该指针存储
p
main()
中的地址,指针本身存储在某处,因此您正在传递指针存储的地址,因此您可以从
alloc2()中修改其内容


注意:强制转换malloc()的返回值是一种不好的方式。

如果在不同的函数中为变量指定不同的名称,会更清楚。由于您有多个名为
p
的变量和参数,并且它们彼此不同,因此很容易混淆

void alloc2(int** pa2)
{
     *pa2 = (int*)malloc(sizeof(int));
     **pa2 = 10;
}

void alloc1(int* pa1) 
{
    pa1 = (int*)malloc(sizeof(int));
    *pa1 = 10;
}

int main()
{
    int *p = 0;
    alloc1(p);
    //printf("%d ",*p);//value is undefined
    alloc2(&p);
    printf("%d ",*p);//will print 10
    free(p);
    return 0;
}
除了重命名函数的参数外,我还将
main()
中的
p
初始化为零(空指针)。您未初始化它,这意味着即使访问它的值(将其传递给
alloc1()
)也会产生未定义的行为

p
为空时,
alloc1()
也会接收空指针作为
pa1
的值。这是
main()
p
值的本地副本。然后,调用
malloc()
会更改
pa1
的值(并且对
main()
中的
p
没有影响,因为它是一个不同的变量)。语句
*pa1=10
将malloced
int
设置为
10
。由于
pa1
是本地的
alloc1()
alloc1()
返回时,它就不存在了。
malloc()
返回的内存不是
free()
d,尽管(
pa1
不再存在,但它指向的并不存在),因此结果是内存泄漏。当控件传回
main()
时,
p
的值仍然为零(NULL)

调用
alloc2()
是不同的,因为
main()
传递
p
的地址。这是
alloc2()
pa2
的值。
*pa2=(int*)malloc(sizeof(int))
语句确实将
main()
p
的值更改为
malloc()
返回的值。语句
**pa2=10
然后将动态分配的
int
更改为
10

还要注意的是,
malloc()
的结果上的
(int*)
在C中是不必要的。如果需要,它意味着

  • 您尚未执行
    #包含
    。类型转换强制代码进行编译,但严格来说,
    int
    的任何使用都会产生未定义的行为。如果是这种情况,请删除
    int*
    并添加
    #include
  • <> LI>使用C++编译器编译C代码。
    “双指针”是普通指针。它们只是指向其他指针的指针。就像“单指针”是指向非指针的指针一样。谢谢peter,所以我理解范围,按值传递,按引用传递。我不明白为什么这不是:
    pa2=(int*)malloc(sizeof(int))
    :pa2=(int*)malloc(sizeof(int))
    (没有
    *
    )。因为使用
    *
    实际上是在解引用它所指向的地址。如您所见,
    p
    指向NULL…@int80
    p
    具有值
    0
    ,但传递给
    alloc2()
    的是
    &p
    ,它是指向
    p
    的指针。因此参数
    pa2
    是指向
    p
    的指针,而不是空指针。因此,当
    pa2
    *
    解除引用时,您将为
    p
    分配一个值。因此,在第一次解除引用时,您实际上将malloc给定的地址存储到
    pa2
    中,而不是存储一个common值?因此,可以通过解引用double来存储值?我现在可能明白了:)所以我不明白的是那些行:
    *p=(int*)malloc(sizeof(int))
    **p=10。。。这一定是去参考了?