2009-08-05 9 views
0

私は関数fun1の2つのレイヤーを通過し、func2はfunc3を呼び出します。私は基本的にint * ptrを呼び出しスタックの最下位の "レベル"を使用してポインタを全部抜きます。私はint配列のためにメモリを動的に割り当てる別の関数も持っています。最上位レベル(func1レベル)では、渡されたポインタに対して常にnullが返されます。私はfunc3まで追跡しており、割り当てられたメモリは値でいっぱいになっていますが、呼び出しスタックがfunc3 - > func2を巻き戻すと突然ポインタが消えてしまいます(0x0000_0000)?私はfunc3レベルでは基本的にptr = allocate_ptr_arrayとは言いませんが、その戻り値からはNULLになります。私が記憶を解放しなかったにもかかわらず、世界では何が起こっているのですか?私は自分の質問が混乱していることを知っている。私はこれがデバッガで起こっているのを見ましたがポインタの質問

+1

私は自分自身の前でこれにぶつかることを覚えています。なぜそれが起こったのかを理解することはかなり困難です。良い質問は、あまり一般的なタイトルを使用することができます。 – Anton

答えて

6

ポインタは基本的に値渡しです。外部関数に割り当てられたメモリを取得するには、ポインタ(int ** p)へのポインタを渡す必要があります。いくつかのコードとAJさん(完全に正しい)答え照らすために

function1(int *p) 
{ 
p = //allocate memory using malloc 
} 

function2(int **p) 
{ 
*p = //allocate memory using malloc 
} 

function3() 
{ 
int *p; 
function1(p); 
// in this case pointer is passed by value. 
//The memory allocated will not be available in p after the function call function1. 

int **p; 
function2(&p); 
//in this case pointer to pointer p has been passed. 
// P will have the memory allocated even after 
//the function call function1 
} 

}

+0

あなたは私がこれを持つことができないという意味ですか? func1(void){int * ptr; func2(int * ptr); //単に型のスタイルを表示しています) } func2(int * ptr){func3(int * ptr); } func3(int * ptr){do_some_work_on_malloced_array; ptr =&array [0]; } あなたは、コールが巻き戻されると削除されることを意味しますか?私がptrにNULLに気づくfunc2にあります。私はあなたがそれを通話することができると思いましたか? –

+0

削除されません。 func3に割り当てられたメモリへのアドレスは、外部関数では使用できません。そのメモリリークは基本的に。 –

+0

あなたはもう1つのことをすることができます。 func3をパラメータとして取る代わりにint *を返すようにします。外部関数では、int * p = func3();を追加します。これは、内部関数 –

2

void func1(void) 
{ 
    int *int_array; 

    func2(&int_array); 

    /* Some stuff using int_array[0] etc */ 

    /* ... */ 

    free(int_array); 
} 

void func2(int **a) 
{ 
    /* ... stuff ... */ 

    func3(a); 

    /* .... stuff ... */ 
} 

void func3(int **a) 
{ 
    (*a) = malloc(N * sizeof **a); 
} 
+0

に割り当てられたメモリへのポインタを取得するようにするため、基本的には、ポインタが下位レイヤに割り当てられているため、ポインタをすべて下に移動する必要がありますか?これは私にとって新しいものです。通常はfunc1のように割り当ててから、その "配列"をサイズとともに渡します。残念なポインタは、常に私を投げる! –

+0

はい、最下位レベルに存在する変数の値を更新する必要があるため、その変数へのポインタを渡す必要があるためです。この場合の変数は既にポインタなので、ポインタをポインタに渡すことになります。別の方法としては、下位の関数が新しいポインタ値を返すようにし、戻り値をトップレベルのint_arrayに明示的に代入する方法があります。これが、標準ライブラリ関数がどのように機能するのかです。 – caf

+0

私は実際には2つの配列を返すようにしています:(したがって、私はそれをparamsで処理する必要があります)。 –

0

ここでは、将来の参照さようなら、他の人のための良い例です。実装後、これらの人に感謝します。

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

void func3(int **ptr) 
{ 
    int i; 
    (*ptr) = (int *)malloc(25*sizeof(int)); 

    for (i=0; i < 25; i++) (**ptr) = i; 
    printf("func3: %d\n",ptr); 
} 

void func2(int **ptr) 
{ 
    func3(ptr); 
    printf("func2: %d\n", ptr); 
} 
void func1(void) 
{ 
    int *ptr; 
    printf("ptr before: %d\n", ptr); 
    func2(&ptr); 
    printf("ptr after: %d\n", ptr); 
} 

void func4(int **ptr) 
{ 
    static int stuff[25]; 
    printf("stuff: %d\n",stuff); 
    *ptr = stuff; 
} 

int main(void) 
{ 
    int *painter; 
    func1(); 
    func4(&painter); 
    printf("painter: %d\n", painter); 
    return 0; 
}