2

このコードでは、 relied onがから whengdbp変更されます(予想どおり)。0x6020100x0NULL

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

int main()
{
    int a = 10;

                        // gdb output
    int *p = (int *) malloc(sizeof(int));   // p = (int *) 0x602010
    p = NULL;               // p = (int *) 0x0
    p = &a;                 // p = p = (int *) 0x7fffffffe15c           

    return 0;
}

しかし、がinpの外で変更された場合、変更されないと思いますが、その理由はわかりません。main()task()0x0

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

void tast(int *p);

void task(int *p)
{

/*
 before
 (gdb) p p
 $1 = (int *) 0x7fffffffe15c         (same as variable a)
 (gdb) p &p
 $2 = (int **) 0x7fffffffe128
*/

    p = NULL;

/*
 after
 (gdb) p p
 $3 = (int *) 0x7fffffffe15c        no change?
 (gdb) p &p
 $4 = (int **) 0x7fffffffe128
*/    
}

int main()
{
    int a = 10;

                        // gdb output
    int *p = (int *) malloc(sizeof(int));   // p = (int *) 0x602010
    p = NULL;               // p = (int *) 0x0
    p = &a;                 // p = p = (int *) 0x7fffffffe15c

    // it is possible to change what p points to 
    // after calling task()?
    task(p);

    // p will be NULL?          

    return 0;
}

task() 内で p が 0x0 に変更されないのはなぜですか?

4

4 に答える 4

2

ポインターは、 のような値intです。次のように考えてみてください:関数内で を渡して変更した場合、int関数はそれが変更されることを期待しますか? いいえ、変数は値で渡されるためです。task()task

呼び出すときtaskは、値のコピー (この場合はポインター) を関数に渡します。やりたいことは、ポインターの値を変更することです。つまり、値が格納されている場所へのポインターが必要です。これはポインタへのポインタですint **

代わりは:

void task(int **p)
{
   *p = NULL;
}

task(&p);

の場所を渡しp *ます。

別の例として、今回は を使用intすると、より明確になる可能性があります。

void makeTen(int *valuePointer)
{
    // Change the variable that valuePointer is pointing to. 
    *valuePointer = 10; 
}

void demoFunction()
{
    int x = 5;

    // x == 5

    // Call this with a pointer to the variable X.
    // We are passing the memory address of the variable x.
    makeTen(&x);

    // x == 10

}

これを理解したら、intbe に変更するとint *、元の問題が理解できるようになります。

于 2012-08-22T15:50:34.240 に答える