将指针作为指针传递给另一个函数内部的指针时会发生什么?

时间:2019-05-02 21:39:58

标签: c++ c

有人可以解释如果我将... * p作为foo函数的参数名称传递会发生什么情况

int main()

{

    int i = 10;
    int *const p = &i;
    foo(&p);
    printf("%d\n", *p);

}

void foo(int **p)

{
    int j = 11;
    *p = &j;
    printf("%d\n", **p);

}

5 个答案:

答案 0 :(得分:4)

您将获得一个指向整数的指针。

首先,不要使用**p作为foo函数的参数名称,这会使您感到困惑。改名为**q

现在考虑一下内存使用情况。有一个存储整数值10的存储位置,要引用该存储位置,我们可以使用变量i。现在,我们创建一个指向p的指针i,然后将一个值推入函数foo的调用堆栈中,该值是指向p的指针。我们现在将该指针称为q

因此q是指向p的指针,而i是指向public static string GetToken() { try { var client = new service.CFCGateway(); var credential = new service.validaUsuarioExternoEnvDTO(); credential.login = "xxxxxxx"; credential.senha = "xxxxxxx"; var result = client.validaUsuarioExterno(credential); return result.passaporte; } catch (Exception ex) { return null; } } 的指针。

答案 1 :(得分:1)

让我们在这里看一个简单的例子!我们有一个函数print_address,该函数接受一个地址并将其打印出来。我们将打印一个int的地址,以及指向该int的指针的地址,以及指向该int的指针的指针。

#include <stdio.h>

void print_address(void* addr) {
    printf("Address: %p\n", addr); 
}
int main()
{
    int value = 0;
    int* value_ptr = &value;
    int** value_ptr_ptr = &value_ptr; 

    print_address(&value);
    print_address(&value_ptr);
    print_address(&value_ptr_ptr); 

    return 0;
}

运行此代码时,得到以下输出:

Address: 0x7fffa4936fec                                                                                                                                      
Address: 0x7fffa4936ff0                                                                                                                                      
Address: 0x7fffa4936ff8  

第一个地址为value,第二个地址为value_ptr,第三个地址为value_ptr_ptr。每个地址都比前一个地址高一点,因为每个变量在堆栈中的位置都高一点。

函数调用也会发生同样的事情。当我们调用一个函数时,该函数中所有局部变量的内存都比当前函数中所有局部变量的内存高一点。

#include <stdio.h>

void print_address(void* addr) {
    printf("Address: %p\n", addr); 
}

void f3(int*** ptr) {
    print_address(ptr); 
}
void f2(int** ptr) {
    print_address(ptr);
    f3(&ptr);
}
void f1(int* ptr) {
    print_address(ptr); 
    f2(&ptr); 
}
int main()
{
    int value = 0;
    f1(&value); 

    return 0;
}

这一次我运行它时,输出为

Address: 0x7ffeca71dc2c                                                                                                                                      
Address: 0x7ffeca71dc08                                                                                                                                      
Address: 0x7ffeca71dbe8  

如果您注意到,地址之间的差距更大,那是因为执行函数调用需要额外的堆栈空间。

答案 2 :(得分:1)

不要那样做。您将拥有一个指向堆栈上未定义内存位置的指针。 2eaefoo(&p);之间的任何其他函数调用都必须用新数据覆盖该内存位置。

答案 3 :(得分:0)

j在退出foo后被销毁,因此在foo中调用main之后执行任何操作都是不正确的,直到您在另一个对象上将其重置(我的意思是{ {1}}。

好吧,您正在做的是在整数指针上传递指针。

如您所见,指针通常用于传递数组:

printf("%d\n", *p)

并且指针上的指针用于传递二维数组,例如在void print_array(int* a, int n) { for (int i = 0; i < n; i++) printf("%d ", a[i]); printf("\n"); } 中,int main(int argc, char** argv) { ... }是字符串数组或argv-s数组。

答案 4 :(得分:0)

您不能通过* p,但可以说...

您似乎正在尝试让函数更新父变量-传递&p是正确的方法。但是您要添加太多的取消引用。我强烈建议您阅读以下内容:https://boredzo.org/pointers/

// Let's assume you only have 4 memory locations for variables: 1 2 3 and 4.
// let's call these m[1] m[2] m[3] and m[4]
// i is at 1, p is at 2, j is at 3, and the p inside the function is at 4.
// let's call that second p, q rather
// so you have: m[1..4] = { i, p, j, q }
// now execute the code in your head:

int main()

{

    int i = 10;          // m[1] = 10        
    int *const p = &i;   // m[2] = 1
    foo(&p);             // foo(2)
    printf("%d\n", *p);  // printf m[2]

}

void foo(int **q)        // q = m[m[2]] = m[1] = 10

{
    int j = 11;          // m[3] = 11
    *q = &j;             // m[10] = 3  // segfault!
    printf("%d\n", **q); // printf m[m[10]] = m[3] = 11 // if it didnt' segfault

}

您似乎正在尝试这样做:

#include <stdio.h>

void b(int *q,int n) {
    *q=n;
}

int main() {
 int i=123; 
 int *p=&i; // *p and i are now synonymous

 printf("%i ",i);  
 printf("%i ",*p); // same thing 
 b(p,111);
 printf("%i ",i);
 b(&i,111);a       // same thing
 printf("%i ",i);
}