Reputation:
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.
Upvotes: 0
Views: 170
Reputation: 311058
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.
Upvotes: 3
Reputation: 1
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;
Upvotes: 4
Reputation: 372982
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.
Upvotes: 4