5

次のコードを検討してください。

#include <iostream>

int main()
{
    char* c = new char('a');
    char ac[4] = {'a', 'b', 'c', 'd'};
    unsigned long long int* u = reinterpret_cast<unsigned long long int*>(c);
    unsigned long long int* uc = reinterpret_cast<unsigned long long int*>(&ac[3]);
    *u = 42;
    *uc = 42;
    std::cout<<*u<<" "<<*uc<<std::endl;
}

これは有効なコードと見なされますか、それともメモリ リーク/未定義の動作ですか? 私は尋ねています:

*u = 42;
*uc = 42;

プログラムが到達できないバイトにアクセスしています(推測します)。

4

1 に答える 1

7

*u = 42;厳密なエイリアシング規則に違反することにより、未定義の動作が発生します。*uは type の左辺値でunsigned long longあり、厳密なエイリアシング ルールでは、これは (既に存在する) オブジェクトにアクセスするためにのみ使用でき、型がlong longorであることが示されていますunsigned long long。ただし、コードはそれを使用して の配列にアクセスしますchar

C++ には (C とは異なり) アライン アクセスに関する特定の規則はありません。これは、C++ では、次のいずれかの理由により、未定義の動作を引き起こさずに非境界整列アクセスを実行するコードを記述することができないためです。

  • 厳密なエイリアシング規則に違反しています。
  • オブジェクトが存在しないメモリへのアクセス。
  • アライメントされていないアドレスをplacement-newに提供します。
于 2016-10-07T03:40:51.697 に答える