2012-04-18 9 views
1

をポインタに私はこの問題に出くわしています:のmallocメモリは

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; 
} 
+5

http://c-faq.com/ptrs/passptrinit.html – cnicutar

+0

'p'はローカル変数です。 '* p'はそうではありません。 –

+0

@ cnicutar、ここのいい例、ありがとう! –

答えて

3

ここで留意すべき点は - ポインタと言うとき、私たちは一般的にはpass by referenceのように考える傾向がありますが、必ずしもそうではありません。でも、ポインタはpassed by value

char* strすることができtestに対してローカルであるとchar* psetmemoryにローカルです。したがって、setmemoryで行った変更は、ポインタへのポインタを送信しないとtestに表示されません。

あなたはそれがsetmemoryにこのポインタポイントとして、我々は地元のポインタを返すされているが、それは問題(なしダングリングポインタの問題)ではないことを、この

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; 
} 

ノートのような単一のポインタで動作させることができますスタック上のヒープ上の場所

+0

ありがとう、パヴァン!ありがとう、パヴァン!非常に面白い、そして詳細な説明です^ _^ –

+0

@worldpeaceすべての隣にあるチェックマークをチェックすることによってあなたを助けた答えの一つ**を受け入れることを忘れないでください答え –

+0

申し訳ありませんが、別の素早い新しい質問、なぜここでは "無料"は不要ですか?私はmallocが使われているならいつも自由が必要だと思った? –

0

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

+0

ありがとうございました!^ _^ –

0

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

最初のケース:

int a; 

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

第二の場合:

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! 
} 

サード場合

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! 
} 
0

のorignalコードを渡している。このようなことの

考えます場所の場所呼び出し側は文字列ポインタputを要求します。 'char *'だけを渡すと、呼び出し元は呼び出し元の場所の内容を値渡しします。おそらく初期化されていない値です。

呼び出し先が文字列またはその他の間接構造体を返さなければならない場合は、両方のアスタリスクが必要です。これにより、呼び出し先が呼び出し側ポインタ変数にポインタを返すことができます。

それは意味がありますか?それは私にしましたが、もう一度、私はそれを書きました。

+0

ここにあなたの時間とコードをありがとう!私は非常に感謝します^ _ ^ –

関連する問題