#1
  1. No Profile Picture
    Contributing User
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Feb 2001
    Posts
    1,481
    Rep Power
    15

    char* types and cstrings


    Hi,

    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?

    Code:
    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    int main()
    {
    	char* pstring = "estimation";
    	char* pstring2=new char[strlen(pstring) + 1];
    	strcpy(pstring2, pstring);
    
    	//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"
    	cout<<pstring2<<endl;
    
    	delete [] pstring2;
    	return 0;
    }
    Last edited by 7stud; March 5th, 2003 at 02:13 AM.
  2. #2
  3. jasondoucette.com
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2003
    Location
    Canada
    Posts
    378
    Rep Power
    12
    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 06:36 AM.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Feb 2001
    Posts
    1,481
    Rep Power
    15
    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.
  6. #4
  7. jasondoucette.com
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2003
    Location
    Canada
    Posts
    378
    Rep Power
    12
    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.
  8. #5
  9. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,220
    Rep Power
    2222
    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.
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Feb 2001
    Posts
    1,481
    Rep Power
    15
    "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 07:53 PM.

IMN logo majestic logo threadwatch logo seochat tools logo