469,612 Members | 2,576 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,612 developers. It's quick & easy.

Help with std string

Hi all,
I have a problem related to std::string class. Is it ok to
assign a global string variable to a local string object as shown
below?

I am trying to print the address of local string buffer and then I
print the address of global string buffer and come out to be same, but
I assume that as soon as func method has returned that temporaryString
string must have been deleted and thus the buffer that it might be
holding might get freed unless that buffer is being reused by the
string class.

So doing something like below might depend on the implementation of
std::string class. Can I assume that it would do the right thing?

string globalString;

void func()
{
string temporaryString = "some value";
printf("Address of local strings buffer %x\n",
temporaryString.c_str());
globalString = temporaryString;
return;
}

void someOtherFunc()
{
func();
//Now use the globalString but the address printed below is
same as the one
//printed by the function func which might get deleted /freed
by string class
printf("Address of global string buffer
%x\n",globalString.c_str());
}

Another question I have is related to STL. I was storing char * 's in
STL containers previously, since now I am converting all my char *'s to
string to avoid memory leaks, I wanted to know that shall I make
container of string or container of string references.

For example:
map<const string&, const string &, myComparator>
or
map<const string, const string , myComparator>

Is there some guidelines for that?

Thanks,
Divick

Jan 23 '06 #1
9 7251
* Divick:
Is it ok to
assign a global string variable to a local string object as shown
below?
yes
[snip] So doing something like below might depend on the implementation of
std::string class. Can I assume that it would do the right thing?
no

you have undefined behavior

string globalString;

void func()
{
string temporaryString = "some value";
printf("Address of local strings buffer %x\n",
temporaryString.c_str());
undefined behavior here, c_str() yields a pointer, %x says it's int
[snip] Another question I have is related to STL. I was storing char * 's in
STL containers previously, since now I am converting all my char *'s to
string to avoid memory leaks, I wanted to know that shall I make
container of string or container of string references.

For example:
map<const string&, const string &, myComparator>
or
map<const string, const string , myComparator>

Is there some guidelines for that?


a standard container element must be copyable, your first example isn't.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jan 23 '06 #2
Alf P. Steinbach wrote:
* Divick:
Is it ok to
assign a global string variable to a local string object as shown
below?
yes
[snip]
So doing something like below might depend on the implementation of
std::string class. Can I assume that it would do the right thing?


no


Well, the string class does "the right thing". But I agree that the
reference of "it" in the OPs question is not quite as clear as it could be.
you have undefined behavior
Yes, but that stems from inappropriate use of printf() and not from problems
with the string class.
string globalString;

void func()
{
string temporaryString = "some value";
printf("Address of local strings buffer %x\n",
temporaryString.c_str());


undefined behavior here, c_str() yields a pointer, %x says it's int

To the OP: Let us remove all possibly distracting clutter from your code.
string globalString;

void func() {
string temporaryString = "some value";
globalString = temporaryString;
}

void someOtherFunc() {
func();
std::cout << globalString << '\n';
}
Executing someOtherFunc() will neither produce undefined behavior nor will
it leak memory or ill-behave in any other way. What you observed when
printing out addresses (or some numbers arising from undefined behavior, as
Alf Steinbach pointed out) could just be an indication that your
std::string implementation uses reference counting as an optimization for
string assignments.

Generally, std::string is designed to handle memory management correctly
behind the scenes. That is one of its primary virtues. In particular,
destruction of temporaryString afert the assignement

globalString = temporaryString;

will not affect globalString in any way.
Best

Kai-Uwe Bux
Jan 23 '06 #3
>>undefined behavior here, c_str() yields a pointer, %x says it's int
I don't understand why it has undefined behavior? I understand that
string class must be using some reference counting mechanism to avoid
deletion of data once it has been assigned to another string, but isn't
it that the addresses for both of them would be same. So what is the
harm in printing it.

By the way I am just printing the addresses, but obviously my intention
is not to use that address for some other purpose. I simply wrote that
to specify that the addresses are same for both the addresses and was
curious that does std::string class use reference counting or not.
Since string class uses reference counting (as it seems to me from
above discussion), the addresses would be same (due to which only I
started this thread). Had I known that on whatever platform the string
class would do some reference counting, I wouldn't have asked this
question altogether. Since I was not sure whether string class uses
reference counting or not, that's why I posted to this thread.

Is there something that I am missing in the above discussion or what?

Thanks,
Divick

Jan 25 '06 #4
Divick wrote:
undefined behavior here, c_str() yields a pointer, %x says it's int
I don't understand why it has undefined behavior?


Because the standards say so. C++ inherits printf() from C. The C standard
defines printf() in terms of fprintf(). About this, it says in clause
7.19.6.1/9:

If a conversion specification is invalid, the behavior is undefined.223)
If any argument is not the correct type for the corresponding coversion
specification, the behavior is undefined.

I understand that
string class must be using some reference counting mechanism to avoid
deletion of data once it has been assigned to another string, but isn't
it that the addresses for both of them would be same. So what is the
harm in printing it.
No harm in printing the pointer. The "harm" arises from treating a pointer
as an int within printf(). That is undefined behavior, although on most
platforms, I would expect it to behave exactly as you expected.

By the way I am just printing the addresses, but obviously my intention
is not to use that address for some other purpose. I simply wrote that
to specify that the addresses are same for both the addresses and was
curious that does std::string class use reference counting or not.
Since string class uses reference counting (as it seems to me from
above discussion), the addresses would be same (due to which only I
started this thread). Had I known that on whatever platform the string
class would do some reference counting, I wouldn't have asked this
question altogether. Since I was not sure whether string class uses
reference counting or not, that's why I posted to this thread.
Well, and I hope the responses in this thread have helped understanding why
you got the output you got and why there is nothing wrong with using the
global variables. The undefined behavior thing is just a tangent. Do get
sidetracked.

Is there something that I am missing in the above discussion or what?


I don't think so.

Best

Kai-Uwe Bux
Jan 25 '06 #5
>>Because the standards say so. C++ inherits printf() from C. The C standard
defines printf() in terms of fprintf(). About this, it says in clause
7.19.6.1/9:
If a conversion specification is invalid, the behavior is undefined.223)
If any argument is not the correct type for the corresponding coversion
specification, the behavior is undefined.


What is the correct conversion specifier for printing addresses if not
%x ?

Rest is pretty clear now. Thanks for that.

Divick

Jan 25 '06 #6
Divick wrote:
What is the correct conversion specifier for printing addresses if not
%x ?

%p
Stephan

Jan 25 '06 #7
Stephan Brönnimann wrote:
Divick wrote:
What is the correct conversion specifier for printing addresses if
not %x ?

%p

Correct, but %p expects a void*. This is one of those places where a
cast is required, as printf() is a variadic function.


Brian
Jan 25 '06 #8
Default User wrote:
Stephan Brönnimann wrote:
Divick wrote:
What is the correct conversion specifier for printing addresses if
not %x ?

%p

Correct, but %p expects a void*. This is one of those places where a
cast is required, as printf() is a variadic function.


A pointer of any type can be converted to void*, without a cast.
If you're really worried that the size of void* is different from the
one of A* then do the cast.

Stephan

Jan 25 '06 #9
Stephan Brönnimann wrote:
Default User wrote:
Stephan Brönnimann wrote:
Divick wrote:
> What is the correct conversion specifier for printing addresses
> if not %x ?
%p

Correct, but %p expects a void*. This is one of those places where a
cast is required, as printf() is a variadic function.


A pointer of any type can be converted to void*, without a cast.


Not with a variadic function.

Brian

Jan 25 '06 #10

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

6 posts views Thread by wukexin | last post: by
7 posts views Thread by Alan Bashy | last post: by
1 post views Thread by wukexin | last post: by
3 posts views Thread by Colin J. Williams | last post: by
1 post views Thread by Rahul | last post: by
22 posts views Thread by KitKat | last post: by
reply views Thread by devrayhaan | last post: by
reply views Thread by gheharukoh7 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.