7

私はインタビューでこのコードに出くわしました。

int main()
{
    int **p;
    p = (int **) new int(7);
    cout<<*p; 
    return 0;
}

*pで実行時エラーが発生することを予期していました。しかし、コードを実行すると、出力「0x7」で正常に実行されました。誰かがこれがどのように機能しているか説明してもらえますか?ありがとう。

4

5 に答える 5

5

いくつかの追加の制約が与えられない限り、適切な答えは上記のどれでもありません。基本的に、コードはを割り当て、そのメモリを(を介して)intであるかのように解釈します。最初の問題は、であるため、一般的なケースでは結果が指定されておらず、のサイズがのサイズよりも小さい場合(64ビットアーキテクチャを考えてください)、で割り当てられたサイズを超えて読み取っているときに、結果が未定義の動作になることです。電話。int*reinterpret_castreinterpret_castintint*new

于 2012-04-15T18:40:02.110 に答える
4

新しいintを作成し、値7で初期化します。

int *x = new int(7);

あなたはそれをポインタ(例えばメモリアドレス7または0x07)にキャストします

int **p = (int**) new int(7);

次に、このアドレスをcoutで表示します。

*p is equal to (int*)7

値が7のポインターです。

于 2012-04-15T18:27:20.130 に答える
0
int main()
{
    int **p;                  // declare pointer to pointer called p
    p = (int **) new int(7);  // new allocates integer initialized to value of 7 and returns a pointer.  Cast the pointer to a point to pointer.  p now represents a pointer to a pointer with contents of 0x7.  If you called **p you would get the contents at address 0x7.
    cout << *p; // dereference p, this yields a pointer, which is an int of value 0x7.
}

この質問は、ポインタに関する知識をテストすることを目的としている可能性が高いですが、あまり実用的ではないようです。

于 2012-04-15T18:37:25.267 に答える
0
new int(7);

int値が であるにメモリを割り当て7、それへのポインタを返します。

int **p = (int **) new int(7);

そのメモリを として解釈するようにコンパイラに指示しますint**

cout << *p;

*pアドレスがandであることをコンパイラに伝え、int *その値を出力します。値は0x07です。(int7をアドレスとして扱います)。余分な逆参照はクラッシュを引き起こします (正確には未定義の動作です)。

于 2012-04-15T18:30:52.160 に答える
0
int main()
{
    int **p = (int **) new int(7);
    cout << *p;
}

したがって、メモリのバイトをnew int(7)割り当てsizeof(int)、それへのポインタを返します。メモリがたまたまアドレス X にあるとしましょう。次に、X は にキャストされて(int**)に格納されpます。

*pこれは、 addressの値 7 をとしてint**解釈することを意味します。intXint*

  • sizeof(int*)が より大きい場合、sizeof(int)として読み取ると、 でint*割り当てられたバッファを超えて読み取られますnew- データ型や再解釈に関係なく、常に未定義の動作です。

  • 同じサイズの場合、CPU は整数 7 を含むメモリを読み取ろうとします。int*これは通常、値int*(7)を生成しますが、標準 5.2.10.5 を調べます。

整数型または列挙型の値は、明示的にポインターに変換できます。値をゼロにするためにヌル ポインターを生成する必要はありません。--- end foonote] 十分なサイズの整数に変換され (そのようなものが実装に存在する場合)、同じポインター型に戻されるポインターは、元の値を持ちます。それ以外の場合、ポインターと整数の間のマッピングは実装定義です。

したがって、整数値は何らかのポインター値に変換されることが保証されていますが、未定義のものはありませんが、値は実装で定義されています。それでも、可逆操作であるため、 7 が値 7を生成する可能性が圧倒的に高くなります。これは、「7」を出力するという観察された動作を説明しています。intint*

  • ポインターのサイズがサイズより小さい場合int、値のスライスを読み取り、それをintポインターとして解釈します。エンディアンに応じて、そのスライスは 0 または 7 またはそれ以外のint値になりますが、表示されるポインタ値に変換できる必要があります。
于 2012-04-16T05:33:57.720 に答える