3

変数がある場合は、その変数に関連付けられたメモリアドレスがあり、ポインタ変数の場合、そのメモリアドレスの「値」は、ポインタが指す実際のデータを保持するメモリアドレスへの参照です。 。

だから私が持っている場合:

for (int x = 0; x < 2; x++)
{
    char * a = (char*)malloc(20);
    printf("%p\r\n", &a);
    printf("%p\r\n", a);
}

出力は次のようになります。

    00999999
    04427310
    00999999
    0442ECF0

ご覧のとおり、ループの各パスで宣言されたポインター変数の1番目と3番目のメモリアドレスは同じままです。これは、前の変数がスコープ外になり、次に使用可能なアドレスが同じアドレス。

この一般化をループ内で宣言されたすべての変数に拡張できますか、それとも例外がありますか?

4

2 に答える 2

11

いいえ、これを一般化することはできません。また、a(ポインタではなく、ポインタが指すもの)のメモリが各反復で同じになるとは限りません。この場合、メモリは再利用され、常に同じになる可能性がありますが、保証はありません。

また、メモリリークがあることに注意してください。

于 2012-12-13T13:33:23.213 に答える
3

これがスタックの通常の動作方法です。そして、これは変数の型に依存しません。スタックが下向きに成長すると、多かれ少なかれこのように見えるかもしれません

<top>
|                 |
+-----------------+
| argument1       |
| argument2       |
+-----------------+
| return address  |
+-----------------+
| saved register1 |
| saved register2 |
+-----------------+
| local variable1 | <- base register
| local variable2 |
| x               |
| a               |
|                 | <- stack pointer
<bottom>

コンパイラーは、スタック上のスペースを、いくつかのベース・レジスターに関連する各変数に割り当てます。ループのスコープが終了すると、のスペースはa効果的に「空き」になり、再利用できます。

後で2番目のループがある場合、または他のネストされたスコープがある場合

for (int x = 0; x < 2; x++)
{
    char * a = (char*)malloc(20);
    printf("%p\r\n", &a);
    printf("%p\r\n", a);
}
...
for (int x = 0; x < 2; x++)
{
    char * b = (char*)malloc(20);
    printf("%p\r\n", &b);
    printf("%p\r\n", b);
}

baのためにもう必要ないので、以前に占有されていたスペースを再利用する可能性があります。これはすべて、コンパイラがスタック上のスペースを最適化する方法に依存します。

これは、少なくともコンパイルされたCのような言語でどのように機能するかです。もちろん、他のメモリモデルもあります。

于 2012-12-13T13:44:18.797 に答える