0

I have a miss-understanding with pointers.

const char* p = "Some text";
const char* q = "Some text";
if (p == q)
    cout << "\nSAME ADDRESS!";
cout << "\np = " << p; 
cout << "\nq = " << q; //same outputs "Some text"

In Visual Studio 2015 the syntax if (p == q) doesn't compare addresses, it compares the values... I thought it was supposed to be something like if (*p == *q).

So how do I compare addresses? I thought using if (&p == &q), but it's been said that it would be addresses of pointers, not the address of what they point to.

Community
  • 1
  • 1
  • 5
    How do you know that it is not comparing addresses? (`==` will never compare *contents* of two C-style strings) – crashmstr Feb 18 '16 at 19:11
  • @crashmstr but wouldn't then the output of them be the address? –  Feb 18 '16 at 19:12
  • 2
    `cout << p;` <- `cout` knows how to print a C string's contents. `cout << (void*)p` to print the address. [cout << with char* argument prints string, not pointer value](http://stackoverflow.com/questions/17813423/cout-with-char-argument-prints-string-not-pointer-value) – crashmstr Feb 18 '16 at 19:14
  • @crashmstr WOW! Huge thank you! I am so dumb! –  Feb 18 '16 at 19:15

3 Answers3

4

In Visual studio 2015 the syntax if (p == q) doesn't comparing addresses, it compares the values...

It does compare addresses. String (or other) literals with the exact same content will be optimized to be instantiated only once (at the same address).

To check the actual address use a statement like

cout << (void*)p << ' ' << (void*)q << endl;
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • Well, okay. How can I see that address? –  Feb 18 '16 at 19:14
  • 2
    @JuliaStefanyshyna use the debugger or cast to `void*` so that `cout` does not print the contents of the string (as is usually desired). – crashmstr Feb 18 '16 at 19:15
  • @JuliaStefanyshyna For more see: http://stackoverflow.com/questions/17813423/cout-with-char-argument-prints-string-not-pointer-value – NathanOliver Feb 18 '16 at 19:16
4

I think you're mixing up two different concepts. If you have two pointers p and q of any type, then p == q always compares the addresses stored in the pointers rather than the objects being pointed at. As a result, the statement

if (p == q) 

tests whether p and q are literally pointing at the same object. As to why you're getting back the same objects - many compilers, as an optimization, will pool together all string literals of the same value into a single string literal and set all pointers to share it. This optimization saves space in the binary. It's also why it's undefined behavior to write to a string literal - if you could write to a string literal, then you might accidentally pollute other strings initialized to that literal.

Independently, the streams library is specifically programmed so that if you try to print out a const char *, it will treat that const char* as a pointer to the start of a null-terminated string, and then print out all of the characters in that string.

If you wanted to instead print out the addresses, you can cast the pointers to void* first:

cout << static_cast<const void*>(p) << endl;
cout << static_cast<const void*>(q) << endl;

The reason this works is that the streams library is designed so that if you try to print out a pointer that isn't a character pointer, it displays the address. The typecast basically tells the compiler "please forget that this is actually a char* and instead treat it like a generic pointer."

Similarly, if you want to compare the strings themselves, use strcmp:

if (strcmp(p, q) == 0) {
   // Equal!
}

That said, in C++, you should probably consider using std::string instead of const char*, since it's safer and easier to use.

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
3

Usually it depends on compiler options (implementation-defined) whether the compiler will store identical string literals as one string literal or separatly.

So for this code snippet

const char* p = "Some text";
const char* q = "Some text";
if (p == q)

the condition in the if statement can either evaluate to true or to false.

From the C++ Standard (2.14.5 String literals)

12 Whether all string literals are distinct (that is, are stored in nonoverlapping objects) is implementationdefined. The effect of attempting to modify a string literal is undefined.

Thus in this statement

if (p == q)

there are indeed compared pointers but the result of the comparison is implementation-defined and in general can be controlled by the programmer by means of setting compiler options.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335