472,146 Members | 1,423 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,146 software developers and data experts.

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

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
2 2419
"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
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.

Similar topics

19 posts views Thread by Espen Ruud Schultz | last post: by
13 posts views Thread by Victor Hannak | last post: by
3 posts views Thread by Mathieu Malaterre | last post: by
8 posts views Thread by Jason Heyes | last post: by
7 posts views Thread by JustSomeGuy | last post: by
12 posts views Thread by shalakasan | last post: by
3 posts views Thread by Angus | last post: by
reply views Thread by Saiars | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.