Click here to Skip to main content
15,891,864 members
Please Sign up or sign in to vote.
2.00/5 (2 votes)
See more:
C++
//Case 1
char * p = "ram" ;

//compare it with a constant literal string
if( p == "ram")
{
  //condition1
  int i= 1;
}

//case2
char* q = new char[4];
memset(q,0,4);
memcpy(q,"ram",3);

//compare string q with constant literal string
if( q == "ram")
{
    //condition2
    int i=2;
}


In the above code snippet in C++, I found that in case1, if condition evaluates to true and it enters the condition1 while in case2 when I was allocating q pointer dynamically then if condition evaluates to false and it does not enter in the condition2. Can anyone please explain this behaviour of char* with equality operator.
Posted

Simple: you are comparing two pointers. If there are both pointing at the same place, then they are equal. If they point at different addresses, they are not the same.

p is pointing at a constant string, q is pointing at a memory location (on the stack) which happens to contain the same data, but is not in the same place. (If it was, then any change to the content pointed at by q would affect all the constant references to "ram" which would be a very, very bad thing!)

If you want to compare teh string contents, then use strcmp[^] instead.
 
Share this answer
 
Comments
Rahul from Poona 3-Feb-13 14:48pm    
so this means that p and constant strinf "ram" in if condtion both are pointing to same memory location.Is that true?
My question is what is the underlying mechanism of equality operator in these both case as they both cases seems to be same but behave differently differently.
I know that i can use strcmp function but I want to know underlying mechanism for these case
OriginalGriff 3-Feb-13 15:38pm    
Yes.
The compiler is bright enough (all of them are) to know that it's the same constant, so it only creates one instance, rather than a different instance every time you you the same strung constant.
== applyed to pointers is true if both point to the same memory address.

But you are operating in the dark side of "undefined behavior". When defining a constant (like "ram" is), the compiler is free to optimize or not all of its repetition as a same constant (so always the same address is used)

Depending on compiler type and options settings, may be all "ram" literals are considered the same thing, instantiated only once, and all pointers required to point to it to point to the same address.

Or it may be some or all the "ram" in your code be treated each one independently.

if(p=="ram") may be true or false depending on compiler optimization (will be true if this second "ram" is considered as the same constant as in char* p = "ram".

q=="ram" is always false, because wherever "ram" stays, q points to the block returned by new char[4] (that you never delete, but that's another problem) that happens to contain 'r','a','m','\0', because you copied them in there, but it will certainly be another different place.
 
Share this answer
 
Comments
Rahul from Poona 4-Feb-13 11:52am    
thank u sir.
Instead of using C style null terminated string, you should uses std::string class which avoid that problem and many other problem related to manual string handling.
 
Share this answer
 
Comments
Rahul from Poona 3-Feb-13 14:50pm    
yeah I can use that but I want to know this behaviour exactly
Albert Holguin 4-Feb-13 12:59pm    
It's great that you're trying to understand the underlying behavior... happy learning! :)
Simple way to compare two strings:

C++
#include <iostream>
#include <string>
using namespace std;

int main()
{
    char *p = "ram";
    char *q = new char[4];
    int b=0,i=0;
    if(strcmp(p,q))
    i++;
    else 
    b++;
    cout<<i<<"\n"<<b<<"\n";
    return 0;
}
 
Share this answer
 
v2
Comments
Rahul from Poona 3-Feb-13 14:49pm    
thanks for ur information but that was not my question.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900