Skip to main content
GameDev.net gamedev.net
🔒 Locked

Passing strings by reference

Started by CheeseMonger Dec 18, 2004 at 10:51 AM 4 replies 1k views
Original Post
CheeseMonger
CheeseMonger
Can anyone explain what is happening here? This works:

__declspec(dllexport) int DoStuff(std::string& strString);

__declspec(dllexport) int DoStuff(std::string& strString)
{
	strString.resize(strString.size()+1, 65); //lengthen string by 1
	return 0;
}

int main()
{
	std::string Test("Hello");
	Dostuff(Test);
}

This works:

__declspec(dllexport) int DoStuff(std::string& strString);

__declspec(dllexport) int DoStuff(std::string& strString)
{
	strString.resize(strString.size()+2, 65); //lengthen string by 2
	return 0;
}

int main()
{
	std::string Test("Hello");
	Dostuff(Test);
}

This implodes horribly:

__declspec(dllexport) int DoStuff(std::string& strString);

__declspec(dllexport) int DoStuff(std::string& strString)
{
	strString.resize(strString.size()+3, 65); //lengthen string by 3
	return 0;
}

int main()
{
	std::string Test("Hello");
	Dostuff(Test);
}

Surely you should be able to fiddle with a reference to your heart's content?
CheeseMonger
Endurion
Endurion
Is DoStuff inside a DLL while main isn't?

Usually stl containers will impose troubles with their allocators if passed and modified outside their creation process.

You either modify the string only in the originating thread or use a global allocator (or a custom one), which takes care of different processes.
Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>
CheeseMonger
CheeseMonger
Quote:
Original post by Endurion
Is DoStuff inside a DLL while main isn't?


Yes.

Quote:
Original post by Endurion
Usually stl containers will impose troubles with their allocators if passed and modified outside their creation process.

You either modify the string only in the originating thread or use a global allocator (or a custom one), which takes care of different processes.


But why does it only go wrong after increasing the containers size by three elements or more?

And why am I still allowed decrease the size of the container by any amount?

What are the limits on using the STL this way, and are they documented anywhere?
CheeseMonger
Jingo
Jingo
Which version of the STL are you using? Most basic_string implementations have an internal buffer, e.g. there could be a member char array of length 16 inside the class, meaning memory would only need to be allocated if you go over the size of the buffer.
Enigma
Enigma
For efficiency reasons most STL implementations do not keep the size of their internal storage buffer the same as the size of the string. When the string gets too long for the buffer they reallocate the buffer, typically by growing it exponentially. It looks like your STL implementation has a default buffer size of 8. You can store six characters in it ("Hello" plus a terminating null) and you can grow it by up to two characters, but growing it by three or more characters would overflow the buffer and so it has to be reallocated. This reallocation is what is causing the problem.

Enigma
CheeseMonger
CheeseMonger
On investigating string::capacity() I found that the buffer is 2 larger than the string I pass, which explains the behaviour above. If I know how many elements I wish to add, I should be safe to use string::reserve() to give me the appropriate breathing room before I pass the container.

Cheers for putting me back on track.
CheeseMonger

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.