0
int main()
{
    int *p1,*p2;
    int a;
    p1=(int *)malloc(sizeof(int));
    p2=(int *)malloc(sizeof(int));
    p1=&a;
    p2=p1;
    a=10;
    printf("\n%d\n",*p1);
    printf("\n%d\n",*p2);
    printf("\n%d\n",a);
    return 0;
}

p1=(int *)malloc(sizeof(int));行を削除しても、p2=(int *)malloc(sizeof(int)); 出力は変わりません。理由を教えてください。

4

4 に答える 4

10
p1 = &a 

最初の malloc 行の結果を破棄するだけです。最初の malloc は無意味です。

p2 = p1

p2 に対してもまったく同じことを行います。

p1 と p2 の POINTERS 用のスペースはスタックに割り当てられるため、追加のメモリなしで必要なすべてを割り当てることができます。他の場所にメモリが割り当てられていない整数をそれらに割り当てたい場合にのみ、mallocが必要です。

どちらも a のスタックに割り当てられたメモリを指していますが、ヒープに割り当てたメモリがリークされ、回復または解放できません。a を 10 に設定すると、3 つの印刷行すべてが 10 を出力するため、これが正しいことがわかります。

このため、プログラムはこれら 2 つの malloc 行を除いてのみ正しいものになります。

于 2013-05-18T23:13:34.050 に答える
1

2 つの malloc ステートメントは、2 つの整数を格納するためのメモリを割り当て、それらのアドレス (ポインター) をそれぞれ p1 と p2 に割り当てます。したがって、次の行の後:

p1=(int *)malloc(sizeof(int));
p2=(int *)malloc(sizeof(int));

p1 と p2 は、malloc によって割り当てられたばかりの 2 つの異なるメモリ位置を指しています。

この線:

p1=&a;

整数 a のアドレスを p1 に割り当てるため、p1 は新しく割り当てられたメモリを指しなくなります。代わりに、整数 a を指します。

この線:

p2=p1;

p1 には a のアドレスが含まれており、p2 にはこの行の後に整数 a のアドレスも含まれているため、p1 の内容を p2 に割り当てます。この時点で、p1、p2 はどちらも整数 a を指しています。

この線:

a=10;

値 10 を整数 a に割り当てます。p1 と p2 は両方とも整数 a を指しているため、*p1、*p2、および整数 a の結果はすべて 10 になります。

以前に malloc によって割り当てられたメモリは、それらへのポインタ ポイントがないためメモリ リークを引き起こし、したがってそれらを解放する方法はありません。これらの 2 行を削除しても結果には影響しません。

p1=&a;
p2=p1;

それらは孤立し、メモリがリークします。

于 2013-05-18T23:30:03.863 に答える
0

質問: 「行 p1=(int *)malloc(sizeof(int)); と p2=(int *)malloc(sizeof(int)); を削除しても、出力は変わりません。理由を教えてください。 "

回答: p1 に a のアドレスを割り当ててから、現在 p1 に格納されているアドレスを p2 に割り当てるため、p1 と p2 に割り当てられたメモリをもう使用しないためです。

おそらくコード内でよりよく説明されています

int main()
{
    int *p1,*p2;                     // define two pointers to int
    int a;                           // define an int variable (space for an int in memory must be reserved)
    p1=(int *)malloc(sizeof(int));   // get memory large enough for an int. (int *) makes the default return value of pointer to void a pointer to int
    p2=(int *)malloc(sizeof(int));   // same thing but for the other point
    p1=&a;                           // overwrite p1 and puts in it the address used for integer variable a
    p2=p1;                           // overwrite p2 with what p1 has and that is the address of integer variable a
    a=10;                            // now put where the integer variable a has its address the value 10 to
    printf("\n%d\n",*p1);            // output what p1 points to (and it points to address of integer variable a)
    printf("\n%d\n",*p2);            // same for p2
    printf("\n%d\n",a);              // just output a
    return 0;
}

変数による追跡

int main()
{
    int *p1,*p2;
    int a;                           // &a = 0xDDDDDDDD
    p1=(int *)malloc(sizeof(int));   // p1 = 0xAAAAAAAA
    p2=(int *)malloc(sizeof(int));   // p2 = 0xAAAAAAAD
    p1=&a;                           // p1 = 0xDDDDDDDD 
    p2=p1;                           // p2 = 0xDDDDDDDD 
    a=10;                            // a=10 (at address 0xDDDDDDDD)
    printf("\n%d\n",*p1);            
    printf("\n%d\n",*p2);
    printf("\n%d\n",a);
    return 0;
}

アドレスがどのようaにそのアドレスを取得したかについての 1 つの追加のメモ。これは、関数に入るときに作成され、終了時に破棄される自動変数です。したがって、a宣言されているだけで何も割り当てられていませんが、メモリが割り当てられています。

K&R 付録 A からの引用

A4.1 ストレージ クラス

.. 自動オブジェクトはブロックに対してローカルであり、ブロックから出ると破棄されます。ブロック内の宣言は自動オブジェクトを作成します...

于 2013-05-18T23:28:29.517 に答える
0
  • 行 p1=(int *)malloc(sizeof(int)); を削除すると p2=(int *)malloc(sizeof(int)); 出力は変わりません。理由を教えてください。

xaxxonはすでに正しい答えを出しましたが、ここで私の別の説明をします。

p1 と p2 はポインターではないとします。次に、コードは次のようになります。

int p1,p2;
int a;
p1=6354; // some number (because malloc returns some number)
p2=6376; // some number
p1=a;
p2=p1;

ラインを外すと

p1=6354; // some number
p2=6376; // some number

出力は変わりません。

于 2013-05-18T23:28:44.440 に答える