• Advertisement

Archived

This topic is now archived and is closed to further replies.

Whats the difference between char* and " "

This topic is 5788 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi I am using map from the STL, and have a question. I create the map as follows
	std::map< char*, int > Script;
 
I then create a variable
	char *name = (char*)(malloc( sizeof(char) * 4 ));
	strcpy( name, "Var1" );
 
or
	char name[4];
	strcpy( name, "Var1" );
 
I then Set Some values in the map
	Script["Var1"] = 45;
 
Now when I try and access the variable as follows
	int iVal = Script[name];
 
I get 0, whereas with
	int Val = Script["Var1"];
 
I get 45; If I strcmp("Var1", name) they match so why dont I get the correct output. Thanks Giant "Only two things are infinite, the universe and human stupidity, and I''m not sure about the former." --Albert Einstein

Share this post


Link to post
Share on other sites
Advertisement
When using std::map< char*, int > you
put a pointer to a memory address in the map.

This means when using Script["Var1"]
"Var1" points to a different address than name.

You could use std::map.

Share this post


Link to post
Share on other sites
quote:

char *name = (char*)(malloc( sizeof(char) * 4 ));
strcpy( name, "Var1" );

or

char name[4];
strcpy( name, "Var1" );



Both assume that "Var1" is four characters long which is, as already said, not true. "Var1" = 'V' 'a' 'r' '1' '\0'. Makes five. The '\0' (or just 0) is the string termination symbol, you have to close your character arrays with it whenever the documentation says it wants a "null-terminated" string. If you do not, the function will read to the first zero in memory counted from the memory position you passed. That means it will only work out correctly if you're in luck and the memory byte next to your end-of-string is a zero. However, try to avoid arrays (not only of characters, but in general). For strings, use std::string instead, as also said above (it will handle those null-termination for you, along with other cool things). However, a fixed version of the quoted code should be this:

char *name = (char*) malloc (sizeof (char) * 5));
strcpy (name, "Var1");

or

char name[5];
strcpy( name, "Var1" );

[Edit]
char name[] = "Var1";
would also do


[Edit]argh, how does that work?
[url=http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.16]Arrays are evil[/url]
[url=http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.5]Arrays are evil[/url]
[url=http://www.parashift.com/c++-faq-lite/proper-inheritance.html#faq-21.5]Arrays are evil[/url]
[url=http://www.parashift.com/c++-faq-lite/containers-and-templates.html#faq-31.1]Arrays are evil[/url]

[Edit]To answer your actual question, the difference between a string enclosed in '"' and a char* is that with the '"'s the terminating zero is automagically added, whereas with char-arrays you have to know about (and store additional memory for) the zero.


quote:

If I strcmp("Var1", name) they match so why dont I get the correct output.


No idea, the documentation says strcmp wants a null-terminated string, maybe you actually were in luck when trying it?

[edited by - Saib on April 18, 2002 1:10:42 PM]

[edited by - Saib on April 18, 2002 1:19:25 PM]

Share this post


Link to post
Share on other sites
Half the problem is that "Var1" takes 5 bytes when using strcmp functions.

The other half of the problem is that your map is using operator < on char*, which does not do a string comparison--it does a pointer comparison.

Both halves of the problem are fixed by using std::string, whose built-in operator < does a lexicographical (CASE SENSITIVE) comparison.

Share this post


Link to post
Share on other sites
Map uses std::less to compare the keys by default. Which means that it is comparing the char* pointers, not the C-strings. You'd be better off using std::strings

If you persist in your use of C strings, create your own predicate (based, for example, on std::lexicographical_compare, or directly on strcmp) and pass it to the std::map as follow :

std::map<char*, int, CStrCompare>


class CStrCompare
{
public:
bool operator()(const char* str1, const char* str2) const
{
return (strcmp( str1, str2 ) < 0 );
// you know the semantics of strcmp don't you ?
}
};


Note: any guru to check my code ?
Edit: Here, I fixed it.

[Questions (STFW) | GDNet Start Here | GDNet Search | Forum FAQ | Google | Asking Smart Questions ]
[Docs (RTFM) | MSDN | SGI's STL | OpenGL | File formats]
[C++ Must Haves (RTFS) | MinGW | Boost | Loki | FLTK | SDL ]

Stolen from Magmai Kai Holmlor, who held it from Oluseyi, who was inspired by Kylotan...


[edited by - Fruny on April 19, 2002 2:50:17 PM]

Share this post


Link to post
Share on other sites
er, not exactly perfect, at least according to my docs the conditional should be:
return (strcmp( str1, str2 ) < 0);

At least my little MSVC documentation doesn't say it will return -1 exactly--just a number that's < 0.

Oh, and it should really be a const function.

[edited by - Stoffel on April 18, 2002 8:34:59 PM]

Share this post


Link to post
Share on other sites

  • Advertisement