By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,386 Members | 1,727 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,386 IT Pros & Developers. It's quick & easy.

One more reason for using std::string instead of char * in C++ programs.

P: n/a
Hello,

Consider the following program. There are two C style string stack variables
and one C style string heap variable. The compiler may or may not optimize
the space taken up by the two stack variables by placing them at the same
address (my g++ compiler does this). Therefore the output of the given
C program is compiler dependent. What is worse, the program does not
do what its writer most likely intended, since, std::set's find()
method uses an implicit == operator for comparison, which in this
case does an address comparison (no way to do an strcmp in this
case seems possible). So the problem is simply solved by using
the string class which was in the mind of the designers of C++
when the STL was created, namely, std::string.

Regards,

Neil
---------------- code follows -------------------------------------------

#include <iostream>
#include <cstdlib>
#include <set>

int main() {
std::set<char *> foo;
foo.insert("hello");

char *bar1 = "hello", *bar2;
if ((bar2 = (char *) malloc(6)) == 0) {
std::cout << "not enough memory" << std::endl;
exit(EXIT_FAILURE);
}

if (foo.find(bar1) != foo.end())
std::cout << "hello" << std::endl;
else
std::cout << "good night" << std::endl;

if (foo.find(bar2) != foo.end())
std::cout << "hello" << std::endl;
else
std::cout << "good night" << std::endl;

}
Jul 22 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
"Neil Zanella" <nz******@cs.mun.ca> wrote in message
news:b6**************************@posting.google.c om...
Hello,

Consider the following program. There are two C style string stack variables and one C style string heap variable. The compiler may or may not optimize
the space taken up by the two stack variables by placing them at the same
address (my g++ compiler does this). Therefore the output of the given
C program is compiler dependent. What is worse, the program does not
do what its writer most likely intended, since, std::set's find()
method uses an implicit == operator for comparison, which in this
case does an address comparison (no way to do an strcmp in this
case seems possible). So the problem is simply solved by using
the string class which was in the mind of the designers of C++
when the STL was created, namely, std::string.

[snipped code that uses std::set<char*>]

Also, allocating the character arrays can be a pain because it can lead to
an off-by-one error for the null terminator, and you are forced to manually
deallocate any c-style strings that you dynamically allocated for the
std::set. There are many reasons why C-style strings are a pain when
compared to std::string.

Nitpick: std::set<char *> uses the std::less<char *> comparison (a default
template parameter) to determine equality. The unexpected behavior's pretty
much the same, though. This behavior could be eliminated by providing a
comparison functor template parameter that "understands" c-style strings
(e.g. std::set<char *, CStringLessThan>).

--
David Hilsee
Jul 22 '05 #2

P: n/a
On 29 Jul 2004 17:17:43 -0700, Neil Zanella <nz******@cs.mun.ca> wrote:
Hello,

Consider the following program. There are two C style string stack
variables
and one C style string heap variable. The compiler may or may not
optimize
the space taken up by the two stack variables by placing them at the same
address (my g++ compiler does this).
It seems unlikely since both variables are in use at the same time.
Therefore the output of the given
C program is compiler dependent.
This is incorrect, you seem to be confusing the address of the variable
itself, with the address that each variable hold (each variable being a
pointer). Its the address that the variable holds that is used to search
in the set.

However the output is compiler dependent, but it depends on whether the
two string literals "hello" have the same address, and I believe that is
compiler dependent.
What is worse, the program does not
do what its writer most likely intended, since, std::set's find()
method uses an implicit == operator for comparison, which in this
case does an address comparison
That I can't disagree with.
(no way to do an strcmp in this
case seems possible).
It's possible by supplying a custom comparision object.

struct StrCmp : public std::binary_function<char*, char*, bool>
{
bool operator()(char* x, char* y)
{
return strcmp(x, y) < 0;
}
};

std::set<char *, StrCmp> foo;
So the problem is simply solved by using
the string class which was in the mind of the designers of C++
when the STL was created, namely, std::string.

Can't disagree that, using a std::string as the key is normally what you
should do.
Regards,

Neil


john
Jul 22 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.