1

charへのポインタへのポインタを使用しているときにこの問題に遭遇しました:

void setmemory(char** p, int num)
{
    *p=(char*)malloc(num);
}

    void test(void)
    {
        char* str=NULL;
        setmemory(&str,100);
        strcpy(str,"hello");
        printf(str);
    }

int main()
{
    test();
    return 0;
}

上記のコードは正しいですが、なぜここでポインターchar ** pへのポインターを使用するのか理解できませんか?代わりにcharへのポインタを使用するのはなぜですか?だから私はこのスニペットを以下に変更し、それが機能していないことがわかりました、誰かが理由を教えてもらえますか?ありがとう!

void setmemory(char* p, int num)
{
    p=(char*)malloc(num);
}

void test(void)
{
    char* str=NULL;
    setmemory(str,100);
    strcpy(str,"hello");
    printf(str);
}

int main()
{
    test();
    return 0;
}
4

4 に答える 4

3

ここで注意すべきことの 1 つは、ポインターと言うとき、一般に、pass by reference必ずしもというわけではありませんが、その観点から考える傾向があることです。ポインターでさえpassed by value

char* strは にローカルでtestchar* pは にローカルsetmemoryです。したがって、ポインターにポインターを送信しないと、変更setmemoryは に表示されません。test

このような単一のポインターで動作させることができます

 char * setmemory(char* p, int num) // p is a new pointer but points at the same
                                    // location as str
{
    p=(char*)malloc(num); // Now, 'p' starts pointing at a different location than 'str'
    strcpy(p ,"hello");  // Copy some data to the locn 'p' is pointing to
    return p; // Oops. The poor `str` is still pointing at NULL :( 
              // Send him the address of the newly allocated area
}

void test(void)
{
    char* str=NULL;
    str=setmemory(str,100); // We are passing a pointer which is pointing to NULL

    printf(str); //Now str points to the alloced memory and is happy :)
}

int main()
{
    test();
    return 0;
}

ではローカル ポインターを返していますsetmemoryが、このポインターはスタックではなくヒープ上の場所を指しているため、問題はありません (ダングリング ポインターの問題はありません)。

于 2012-04-18T13:43:40.830 に答える
0

ポインタを変更したい、つまり、関数には値ではなく参照が必要です。C では、これは変数にアドレス (ポインター) を与えることによって行われ、ポインター自体を変更します。したがって、1 つのポインターは参照用であり、もう 1 つはプログラム ロジック用です。

于 2012-04-18T13:43:32.750 に答える
0

ここでは、ローカル変数 *p のみを設定しています。データへのポインターではなく、データへのポインターを取得していることに注意してください。

次のように考えてください。

最初のケース:

int a;

foo(a); // Passes a
void foo(int b)
{
  b = 4;    // This only changes local variable, has no effect really
}

2 番目のケース:

int a;
foo(&a); // Passes *a

void foo(int *b)
{
  *b = 4; // This changes the contents of a. As you can see we have not changed the original pointer!
  b = 4; // This changes our local copy of the pointer, not the pointer itself, like in the first case!
}

3番目のケース

int *ptr;
foo(&ptr); // Passes **ptr

void foo(int **b)
{
  **b = 4; // This changes the data of the passed pointer
  *b = 4; // This changes the passed pointer itself, i.e. it changes ptr. This is what test() is doing, the behavior you are looking for!
  b = 4; // This changes our local copy of a variable, just like the first case!
}
于 2012-04-18T13:48:52.583 に答える
0

元のコードは、呼び出し元が文字列ポインターを置きたい場所に渡されます。「char*」のみを渡すと、呼び出し元は呼び出し元の場所の内容を値で渡します。おそらく初期化されていない値です。

呼び出し先が文字列またはその他の間接構造体を返す必要がある場合は、呼び出し先が呼び出し元のポインター変数にポインターを返すことができるように、両方のアスタリスクが必要です。

それは理にかなっていますか?それは私にやったが、もう一度書いた。

于 2012-04-18T13:48:54.077 に答える