1

main()は、引数パラメーターFirst Nodeを使用してCall_By_Test()関数を呼び出します。Call_By_Test()で最初のノードを解放しましたが、main()で最初のノードアドレスが解放されません。なぜですか?

typedef struct LinkList{
int data;
struct LinkList *next;
}mynode;

void Call_By_Test(mynode * first)
{
        free(first->next);
        first->next = (mynode *)NULL;
        free(first);
        first = (mynode *)NULL;
}
int main()
{
mynode *first;

first = (mynode *)malloc(sizeof(mynode));
first->data = 10;
first->next = (mynode *)NULL;

cout<<"\n first pointer value before free"<<first<<endl;

Call_By_Test(first);
// we freed first pointer in Call_By_Test(), it should be NULL
if(first != NULL)
        cout<< " I have freed first NODE in Call-By-Test(), but  why first node pointer has the value "<<first<<endl;


}

出力:最初のポインター値0x804b008 Call-By-Test()で最初のNODEを解放しましたが、最初のノードポインターの値が0x804b008である理由

4

5 に答える 5

7

答えは、参照渡しを使用していないということです。あなたは値でポインタを渡しています-そしてそれは同じことではありません。つまり、ポインタが参照するデータに変更が表示されますがfirst、Call_By_Testメソッド内でそれ自体の値を変更しても何も起こりません。

于 2010-02-15T13:52:24.593 に答える
5

質問にはc++のタグが付いているので、次のようにリファクタリングします。

void Call_By_Test( mynode *& first ) // rest of code remains the same

これは、余分な間接参照なしで参照渡しを伝達します。ポインターをポインター(void Call_By_Test( mynode ** first ))に渡すことを提案するすべてのソリューションは、ポインター変数へのポインターで値渡しのセマンティクスを使用しています。これはC++で実行できますが、参照渡しの方が明確です。

于 2010-02-15T14:00:38.170 に答える
3

関数内

void Call_By_Test(mynode * first)

1つ目は、事実上、関数のローカル変数です。それを変更しても、プログラムの残りの部分の状態は変更されません。ポインターへの参照またはポインターへのポインターが必要です。

void Call_By_Test(mynode ** first)
{
        free((*first)->next);
        (*first)->next = NULL;
        free(*first);
        *first = NULL;
}

そしてそれを呼ぶために:

Call_By_Test( & first );
于 2010-02-15T13:53:19.947 に答える
1

あなたがするとき:

void Call_By_Test(mynode * first)

最初にコピーするので、最初にあるもので作業できますが、コピーであるため、最初にアドレスを変更することはできません。

最初に値を変更したい場合は、次のような関数が必要です。

void Call_By_Test(mynode ** first)

また

void Call_By_Test(mynode & first)

これにより、元の変数であるかのように(メイン関数からのコピーではなく)最初に引数にアクセスできます。

于 2010-02-15T13:55:13.817 に答える
0

ポインタ(0x804b008など)の場合free、ポインタ自体のビットは変更されません。これは、C ++ライブラリが、指定されたアドレスのメモリが使用されなくなったことを記録できるようにするだけであり、リサイクルすることができます。あなたの場合、印刷する0x804b008と、アドレスのメモリ0x804b008はC++ライブラリで再利用できます。

于 2010-02-15T13:54:55.540 に答える