Help with std string

D

Divick

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
 
A

Alf P. Steinbach

* 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.
 
K

Kai-Uwe Bux

Alf said:
* 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.
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
 
D

Divick

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
 
K

Kai-Uwe Bux

Divick said:
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
 
D

Divick

Because the standards say so. C++ inherits printf() from C. The C standard
What is the correct conversion specifier for printing addresses if not
%x ?

Rest is pretty clear now. Thanks for that.

Divick
 
?

=?iso-8859-1?q?Stephan_Br=F6nnimann?=

Default said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top