0

この記事 ( http://www.codeproject.com/Articles/627/A-Beginner-s-Guide-to-Pointers ) を読んでいました。この記事には、それらを使用する理由の 1 つを説明するコードが含まれています。例えば。ダイナミック アロケーション。

例1。間違ったプログラム:


「このプログラムは、まず SomeFunction 関数を呼び出します。この関数は、nNumber という変数を作成し、pPointer がそれを指すようにします。しかし、問題はそこにあります。関数が終了すると、nNumber はローカル変数であるため削除されます。ローカル変数は、実行が定義されたブロックを離れると常に削除されます. これは、SomeFunction が main() に戻ると、変数が削除されることを意味します. したがって、pPointer は、変数が以前にあった場所を指していますが、これはもはやこのプログラムには属していません. "

#include <stdio.h>

int *pPointer;

void SomeFunction()
{
    int nNumber;
    nNumber = 25;    

    // make pPointer point to nNumber:
    pPointer = &nNumber;
}

void main()
{
    SomeFunction(); // make pPointer point to something

    // why does this fail?
    printf("Value of *pPointer: %d\n", *pPointer);
}

例2。正しいプログラム:


「SomeFunction が呼び出されると、いくつかのメモリが割り当てられ、pPointer がそれを指すようになります。今回、関数が戻ると、新しいメモリはそのまま残されるため、pPointer はまだ何か有用なものを指しています。動的割り当てはこれで終わりです!」

#include <stdio.h>

int *pPointer;

void SomeFunction()
{
    // make pPointer point to a new integer
    pPointer = new int;
    *pPointer = 25;
}

void main()
{
    SomeFunction(); // make pPointer point to something
    printf("Value of *pPointer: %d\n", *pPointer);
}

私の質問:


上記の説明は私にとって完全に理にかなっていて、ポインターを使用する理由については気分が良かった. 次に、プログラムを実行して何が起こるかを確認することにしました。25 が削除されたため、最初の 1 つに *pPointer の乱数が表示されることを期待していました。両方のプログラムで、「Value of *pPointer: 25」が正しく表示されました。チュートリアルが言ったように、最初のプログラムは失敗するべきではありませんでしたか?

4

6 に答える 6

0

最初のプログラムでは、ポインターは引き続き、数値 25 が格納されているメモリ内の場所を指しています。正解です。問題は、25 という数字が上書きされたということではありません。上書きされた可能性があるということです。他のプログラムには、最初のプログラムの境界を超えることなくそのメモリ位置をいじる自由なライセンスがありますが、何かが実際にその値を変更するようになるまで、ハードウェアは引き続き 25 という数字を保存します。

于 2013-07-02T13:22:56.220 に答える
0

最初のプログラムが機能した理由は、C++ では破棄された変数へのポインターを使用することが定義されていないためです。しかし、c++ が指示しないのは、そのメモリに何が起こるかです。ローカル変数は、C++ でスタック フレームと呼ばれるものを使用して割り当てられます。または、関数の完了後にアセンブリ言語の「スタック」に精通している場合、メモリは実際には破棄されず、上書きから保護されないことがよくあります。そのため、そのポインターが機能する場合もありますが、別の時点で、指しているメモリも上書きされる可能性があります。

この現象の技術的な説明は、関数が入力されると、そのアドレスがスタック セグメントにプッシュされることです。ローカル変数は、このプッシュされたアドレスとスタック ポインターの下のオフセットとして定義されます。これにより、ローカル変数にアクセスするためのスタック上のメモリが効果的に提供されます。しかし、そのメモリを上書きする時間を無駄にするのではなく、関数が終了すると、メモリは後の操作からの読み取りと書き込みに対して保護されないままになります。そのような動作は未定義です。有効かどうかは決まったものではなく、しばしば変動します。説明をお探しの場合は、このビデオで、ハードコアな詳細に入ることなく概要を説明しています: http://www.youtube.com/watch?v=vcfQVwtoyHY .

于 2013-07-02T13:13:29.343 に答える