2016-01-04 5 views
5

私はポインタを理解しようとしています。このコードを読んで、コンパイルして実行するたびにアドレスが変わります。それはいくつかの迷惑な値ですか、またはポインタは実際に外出先で割り当てられたメモリを取得しますか?Cでプログラムを実行するたびにポインタアドレスが変わるのですか?

私のコマンドプロンプト:

[email protected]:~/Desktop/Learn_C$ ./Practice 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0xbf98fd64 

[email protected]:~/Desktop/Learn_C$ make Practice 
make: 'Practice' is up to date. 

[email protected]:~/Desktop/Learn_C$ ./Practice 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0xbfcce2a4 

[email protected]:~/Desktop/Learn_C$ ./Practice 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0xbfa25df4 

[email protected]:~/Desktop/Learn_C$ ./Practice 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0xbfecf104 

私のCコードは次のとおりです。

#include <stdio.h> 

int main() 
{ 
    int nNumber; 
    int *pPointer; 

    nNumber = 15; 
    pPointer = &nNumber; 

    printf("nNUmber is equal to : %d\n", nNumber); 

    *pPointer = 25; 

    printf("nNumber is equal to : %d\n", nNumber); 

    printf("%p\n", pPointer); 

    return 0; 
} 

は、事前にありがとうございます。

+4

一般的なセキュリティ機能:[アドレス空間レイアウトのランダム化](https://en.wikipedia.org/wiki/Address_space_layout_randomization) –

+1

なぜdownvote。これは正当な質問です。 – alk

答えて

4

ポインタ値を正確に表現する表現または実装は、実装の詳細です。 Cの標準はそれに関する要件を述べていません。コードを実行するたびに、値が同じかどうかは保証されません。

有効なポインタ間のポインタ演算(配列オブジェクト内の2つのポインタの比較など)は、C標準によって定義されています。ところで

、あなたはC標準によって要求されるよう%pで印刷するvoid*へのポインタをキャストする必要があります

printf("%p\n", (void*) pPointer); 

をコメントで述べたように、一部のオペレーティングシステムは、address space layout randamizationを行います。 Linuxではこれがデフォルトで行われます。あなたのコードのために、私はASLRと、次の出力を得る:

$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7fffde18ba7c 
$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7fff981efe0c 
$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7ffdade6837c 
$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7ffced208b4c 

私はそれを無効にした場合:

$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7fffffffeaec 
$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7fffffffeaec 
$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7fffffffeaec 
$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7fffffffeaec 
$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7fffffffeaec 
$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7fffffffeaec 
$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7fffffffeaec 
$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7fffffffeaec 
$ ./a.out 
nNUmber is equal to : 15 
nNumber is equal to : 25 
0x7fffffffeaec 

しかし、これまでのように:

echo 0 > /proc/sys/kernel/randomize_va_space 

それは同じ値を出力しますCの標準については、絶対に値の保証はありません。

1

いくつかのジャンクバリューか、実際にはポインタが実際に外出先で割り当てられていますか?

どちらもありません。ポインティング対象のオブジェクト(nNumber)のアドレスがプログラムの実行ごとに異なっているか、または使用中のポインター表現スタイルが同じアドレスに対して異なる表現を提供しているか、またはその両方のために、印刷するポインター値が異なります。実際には、前者ははるかに可能性が高い。

nNumberのアドレスは、プログラムが(仮想)メモリにロードされる場所の関数であり、何も実行時に一貫している必要はありません。実際、Jeff Mercado氏はコメントの中で、「アドレススペースレイアウトのランダム化」と呼ばれるメカニズムが採用されているため、システムセキュリティを向上させるために意図的にプログラムやライブラリのロードアドレスをランダム化しています。その使用はあなたの観察のためのもっともらしい、そして可能性の高い説明ですが、決して唯一可能なものではありません。

関連する問題