3

コードは次のようになり、次のように出力されます1

int main(int argc, char *argv[])
{
    vector <const char*> vec = {"nima","123"};
    vector <const char*> vec2 = {"nima","123"};
    auto result = equal(vec.cbegin(), vec.cend(), vec2.cbegin());
    cout << result << endl;
    return 0;
}

を使用するだけで、2つのcスタイルの文字列が等しいかどうかをテストできることを知っていました(私が理解したように、オブジェクトではないstrcmpため)。char*しかし、ここequalにからの関数があります<algorithm>==2の等式をテストできるように、演算子をオーバーロードしますchar*か?

@Damonは、私が理解したように、同じ文字列リテラルを同じアドレスにマージするので、それらは等しいと言います。ただし、char*別のアドレスで試しても、同じ結果が得られます。

int main(int argc, char *argv[])
{
char* k = "123";
char* b = "123";
vector <const char*> vec = {"nima"};
vector <const char*> vec2 = {"nima"};
cout << &k << endl;
cout << &b << endl;
vec.push_back(k);
vec2.push_back(b);

auto result = equal(vec.cbegin(), vec.cend(), vec2.cbegin());
cout << result << endl;
return 0;
}

結果は次のとおりです。

 0x7fff5f73b370
 0x7fff5f73b368
 1
4

1 に答える 1

11

ここでおそらく起こることは、コンパイラ/リンカーが、2つが同一である4つの文字列リテラルを2つのリテラルにマージすることです。したがって、両方"nima"と両方"123"が同じアドレスを持ちます。

アドレスをベクトルに格納し、それらを(operator==アドレス上で)比較します。アドレスが同じであるため、比較は等しくなります。

これは偶発的なものであることに注意してください。それは2つの理由のために「機能する」だけです:

  1. 文字列はリテラルです(つまり、egから読み取られた一部の文字列ではありませんstdin)。
  2. コンパイラーは許可されていますが、同一のリテラルをマージする必要はありません(これが発生するかどうかは、実装によって定義されます)。

これは、別のコンパイラを使用している場合、または同じコンパイラを使用している場合に、面白い驚きを得る2つの状況につながる可能性があります(常に「動作」したときに突然動作しない理由を見つける必要がある場合はそれほど面白くありません)最適化設定が異なるコンパイラ、またはリテラル以外の文字列を割り当てる場合。

于 2013-02-16T14:02:39.860 に答える