-1

Please explain why in some cases it is true and in other cases it is false, although in all three cases the addresses of the strings are different?

  1. In the first case, vectors are simply initialized with string literals and then iterators of those strings are passed to the equal function. The result is true. Since C-style strings have no comparison operators, their addresses are compared, but when the addresses of strings in vectors are output, it shows that the addresses are not equal. Why then does the result of the equal function get true?

  2. In the second case, vectors are already initialized from pointers to C-style strings. In this case true is also returned, though again the string addresses are different. Why?

  3. In the third case, vectors are initialized using two-dimensional arrays. In this case, again, the addresses of strings in vectors are different, but this time the output is false

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>

int main()
{
    std::cout << std::boolalpha;

    std::vector<const char*> vec_e{ "String" };
    std::vector<const char*> vec_f{ "String" };
    std::cout << equal(vec_e.begin(), vec_e.end(), vec_f.begin()) << std::endl; // true
    std::cout << &vec_e[0] << std::endl;
    std::cout << &vec_f[0] << std::endl;

    const char* str_a[1] = { "Hello" };
    const char* str_b[1] = { "Hello" };
    std::vector<const char*> vec_a(std::begin(str_a), std::end(str_a));
    std::vector<const char*> vec_b(std::begin(str_b), std::end(str_b));
    std::cout << equal(vec_a.begin(), vec_a.end(), vec_b.begin()) << std::endl; // true
    std::cout << &vec_a[0] << std::endl;
    std::cout << &vec_b[0] << std::endl;

    const char str_c[][6] = { "World" };
    const char str_d[][6] = { "World" };
    std::vector<const char*> vec_c(std::begin(str_c), std::end(str_c));
    std::vector<const char*> vec_d(std::begin(str_d), std::end(str_d));
    std::cout << equal(vec_c.begin(), vec_c.end(), vec_d.begin()) << std::endl; // false
    std::cout << &vec_c[0] << std::endl;
    std::cout << &vec_d[0] << std::endl;

    return 0;
}
iamnotevg
  • 17
  • 5
  • please try to focus on one question. And please include the output in the question (and the output you expected when it differs) – 463035818_is_not_an_ai Feb 06 '23 at 09:41
  • 1
    title asks about comparing strings, but most of the code is about comparing vectors – 463035818_is_not_an_ai Feb 06 '23 at 09:42
  • @463035818_is_not_a_number I wrote that I expected to see false, but for some reason in some cases, as I indicated, the output is true – iamnotevg Feb 06 '23 at 09:44
  • Can you explain WHAT your are trying to do? vec_e is basically a complicated way of modeling a string_view. And what does your "equal" function do? In general just try to avoid using "C" style arrays (doubly so for strings) – Pepijn Kramer Feb 06 '23 at 09:45
  • well ok, clarifying up your misunderstanding is part of the answers. When you say "compare strings" you arent actually comparing strings – 463035818_is_not_an_ai Feb 06 '23 at 09:49

1 Answers1

4

All 3 compare the addresses, not the strings. The first 2 compare the addresses of string literals, which can be the same when the strings are equal.

The first 2 examples can be rewritten as:

const char *a = "Hello";
const char *b = "Hello";
cout << (a == b);

It is implementation defined if a and b point to the same address or if the compiler uses 2 separate string literals.

The third one is:

const char a[] = "Hello";
const char b[] = "Hello";
cout << (a == b);

where the arrays obviously don't have the same address.

The &vec_e[0] are wrong in the std::cout, they should be (void*)vec_e[0], then it will tell you the addresses, which are compared. The cast is necessary, otherwise it would print the string, not the address.

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>

int main()
{
    std::cout << std::boolalpha;

    std::vector<const char*> vec_e{ "String" };
    std::vector<const char*> vec_f{ "String" };
    std::cout << equal(vec_e.begin(), vec_e.end(), vec_f.begin()) << std::endl; // true
    std::cout << (void*)vec_e[0] << std::endl;
    std::cout << (void*)vec_f[0] << std::endl;

    const char* str_a[6] = { "Hello" };
    const char* str_b[6] = { "Hello" };
    std::vector<const char*> vec_a(std::begin(str_a), std::end(str_a));
    std::vector<const char*> vec_b(std::begin(str_b), std::end(str_b));
    std::cout << equal(vec_a.begin(), vec_a.end(), vec_b.begin()) << std::endl; // true
    std::cout << (void*)vec_a[0] << std::endl;
    std::cout << (void*)vec_b[0] << std::endl;

    const char str_c[][6] = { "World" };
    const char str_d[][6] = { "World" };
    std::vector<const char*> vec_c(std::begin(str_c), std::end(str_c));
    std::vector<const char*> vec_d(std::begin(str_d), std::end(str_d));
    std::cout << equal(vec_c.begin(), vec_c.end(), vec_d.begin()) << std::endl; // false
    std::cout << (void*)vec_c[0] << std::endl;
    std::cout << (void*)vec_d[0] << std::endl;

    return 0;
}

will print

true
0x4030a0
0x4030a0
true
0x4030e0
0x4030e0
false
0x7fffd05dcb70
0x7fffd05dcb90
mch
  • 9,424
  • 2
  • 28
  • 42
  • I understand that in all cases addresses are compared, as I described in the question, but why then in some cases the output is true if the compared addresses are not equal? – iamnotevg Feb 06 '23 at 09:49
  • You were printing the wrong pointers, I added the fixed code. – mch Feb 06 '23 at 09:52
  • @iamnotevg two string literals can have same adress when they are the same string. Actually it is rather likely that they do, when in the same file – 463035818_is_not_an_ai Feb 06 '23 at 09:58
  • @iamnotevg example https://godbolt.org/z/99748GxYP – 463035818_is_not_an_ai Feb 06 '23 at 10:01
  • @463035818_is_not_a_number I understood that, so I wrote this sample code to test it. In the end it turned out that I was just outputting the addresses wrong and thought the addresses were really different in all cases. – iamnotevg Feb 06 '23 at 10:02
  • Exactly. `std::cout << &vec_e[0] << std::endl;` prints the address where the `vector` stores the `const char*`, not the address of the `const char*`. – mch Feb 06 '23 at 10:07