March 5th, 2003, 02:13 AM
char* types and cstrings
I conducted a test to narrow down a problem I'm having with some code. In the test below, I assign a string literal to the pointer pstring. Then I try to copy the c style string in pstring to pstring2. Then with an if-statement, I test whether the copy of the string in pstring2 equals the original string, but the if condition fails. Can anyone explain that behaviour?
using namespace std;
char* pstring = "estimation";
char* pstring2=new char[strlen(pstring) + 1];
//if-condition succeeds and the output is diplayed:
if(pstring == "estimation") cout<<"pstring is: "<<pstring<<endl;
//if-condition fails so there is no output????
if(pstring2 == "estimation") cout<<"pstring2 is: "<<pstring2<<endl;
//output is "estimation"
delete  pstring2;
Last edited by 7stud; March 5th, 2003 at 03:13 AM.
March 5th, 2003, 07:32 AM
pstring and pstring2 are pointers. So you are comparing pointers.
I was surprised that your code compiled at all. But, apparently the compiler knows that the string "estimation" is stored somewhere in memory where it cannot be changed, which just happens to be the same place that pstring is pointing to.
So, the pointer to "estimation", and pstring both point to the same place, and therefore are equivalent.
pstring2 points to a dynamically allocated piece of memory, so it doesn't point to the same place as pstring, so the compare fails. The code is not comparing the data that they are pointing to. Try putting this: 'pstring2 = pstring;' right before the compare with pstring2, and you will see that it now succeeds, since this statement makes pstring2 point to the same place as pstring.
You have to think that pstring and pstring2 are just 4-byte variables that hold a 32-bit address. These addresses are what is being compared, regardless of what is stored at the addresses.
Use strcmp for comparing strings.
Last edited by Jason Doucette; March 5th, 2003 at 07:36 AM.
March 5th, 2003, 10:51 AM
It seems to me that I'm not comparing the pointers to each other---I'm comparing each pointer to the string literal "estimation". One of the them equals "estimation" and the other one doesn't.
March 5th, 2003, 01:45 PM
You cannot compare two different types of variables. You are comparing pointers.
As I explained above, the string that you are comparing the pointer to is also a pointer. Why? Because C accesses all strings as pointers (whether there is an actual pointer variable defined that points to it or not). When you reference "estimation", it is the exact same thing as having a variable which is a pointer to it, and accessing its value instead.
How can this be? Because the string is a constant. The string never changes. You may use this string multiple times throughout your program, so the compiler stores it as a constant (meaning you cannot change it) in memory once, and each access to it (such as passing it to a printf statement) is like passing the pointer of the string to it.
Again, remember that you can only ever compare variables of similar types. The fact that one side of the compare is a pointer means the other side is also a pointer. The explanation above should help you understand why C 'sees' it as a pointer.
Strings are difficult in C, I understand. Just keep in mind that everytime you pass a string to a function like printf, whether it be a variable that is an array of chars, or a constant string like "estimation", you are actually passing a pointer to char.
March 5th, 2003, 02:57 PM
Jason's right. pstring points to the original string. strcpy() made a copy of that string in a different location pointed to by pstring2. pstring and pstring 2 are both pointers and they are pointing to two different locations, so they are not equal. BTW, the "Hungarian" prefix of "p" is commonly used to identify a pointer.
As suggested, use strcmp() to compare the two strings. The return value is not quite what we would expect:
< 0 string1 less than string2
= 0 string1 identical to string2
> 0 string1 greater than string2
But the reason I'm responding is to warn of a related problem and a common mistake to watch out for; ie, when you have a function construct and return a string. If you build the string in a char array declared within the function (and not "static"), then when you exit the function that string will go away and attempts to read it will yield garbage.
Some solutions would be:
1. Pass to the function a pointer to a char array either in static memory or within the calling function -- ie, you are sure it will still be around when you try to access it.
2. Within the called function, declare the char array as static and return a pointer to it.
3. Have the called function use a char array declared in static memory.
Just trying to head of trouble before it happens.
March 5th, 2003, 06:03 PM
"You may use this string multiple times throughout your program, so the compiler stores it as a constant (meaning you cannot change it) in memory once, and each access to it (such as passing it to a printf statement) is like passing the pointer of the string to it."
Thanks, that makes sense to me. I like to think I'm pretty informed about c-style strings: I know string literals are constants; I know you can display a char* with cout and you won't get an address, you'll get a string instead; and I know about trying to return variables that are local to a function--my code is actually from a constructor where I'm dynamically allocating memory so the pointer won't go out of scope; and I just discoverd that you could use the pointer name and compare it to a string in an if-statment, but it seems like every time I try to use char* to cstrings, I discover new problems--like this one. I have a hard time knowing whether the char* is going to be treated like an address or a string literal. Hopefully knowing a string literal is a pointer will end this problem forever!
Thanks to both of you for taking the time to explain it.
Last edited by 7stud; March 5th, 2003 at 08:53 PM.