3
int main()
{
    int *ptr, **ptr1;
    ptr = (int*)malloc(sizeof(int));
    ptr1 = (int**)malloc(sizeof(int));
    free(ptr);
    *ptr = 12345;
    ptr1 = &ptr;

    //free(ptr);
    //**ptr1 = 23456;
    printf("%d \n", **ptr1);
    system("pause");
    return 0;
}

メモリがすでに保存されている場合、どのよう*ptrに値を保存しますか? したがって、今 は を指しているはずです。なぜこうなった?12345freedptrgarbage

4

5 に答える 5

8

このコードは、非常に多くのレベルで非常に間違っています。

  1. malloc()Cからの戻り値をキャストしないでください。
  2. 間違ったサイズを割り当てています。ptr1必要sizeof *ptr1ありませんsizeof (int)。ポインターです!
  3. malloc()失敗する可能性があることを覚えておいてください。戻り値を確認してから使用してください。
  4. メモリにアクセスした後は、メモリにアクセスしないでくださいfree()。未定義の動作。

また、ポインタ自体は呼び出し時に破棄されないことに注意してくださいfree()。なくなるのは、ポインタが参照するメモリです。したがって、必要に応じて、ポインターのビットに相当するポインターをポインター自体に格納できます。ただし、これが必要になるケースはめったになく、ビットを検査する場合は注意が必要です。

于 2012-09-06T09:12:57.117 に答える
4

ポインターは解放されますが、割り当てられたときの場所を引き続き指します。これを行うことは、重大なプログラミング エラーと見なされます。しかし、ランタイム環境は (通常) そのようなエラーの識別や修正には役立ちません。

自分に銃を向けて引き金を引かないでください!

于 2012-09-06T09:13:06.017 に答える
3

これは未定義の動作です。何でも起こりえます。

free(ptr);
*ptr = 12345;

違法です。クラッシュしたり、運が悪いと動作しているように見えたりして、ソフトウェアが原子力発電所に出荷されるまで問題を隠している可能性があります。ただし、このようなコードを書いている場合、おそらくそのような企業で働いているわけではありません。:)

于 2012-09-06T09:10:43.577 に答える
1

あなたは未定義の振る舞いを理解していないようです。基本的に、動作は定義されていません。以下を含む(ただしこれらに限定されない)ことは何でもできます。

  1. クラッシュ
  2. 誤って期待していたことを実行してください
  3. エラーを発生させずに、指示したとおりに実行します
  4. コンソールでテトリスのゲームを開始します
  5. ハードドライブを再フォーマットします

解放されたメモリへのアクセスは、一般に(ほとんどのシステムで)機能しているように見えますが、プログラムの他の部分が所有していると見なすデータをランダムに破損します(解放後に割り当てがあったかどうかによって異なります)。

未定義の振る舞いを定義しようとすると、何も見えなくなります。そもそもやらないほうがずっといいです。

于 2012-09-06T09:36:48.350 に答える
0

free() は *ptr が指すメモリを解放しますが、*ptr の値は変更しません。そのため、その値が他のものと競合しない場合でも機能しますが、メモリは別のプロセスによってランダムに割り当てられる可能性があります。一般的な方法は、free(ptr); を実行することです。ptr = NULL を使用すると、別の malloc 呼び出しを行わずにメモリを誤って再利用することを回避できます。

于 2012-09-06T09:20:01.870 に答える