[C++] stl strings retain heap pointer even while copying from temporary to temporary?

Started by
7 comments, last by Agony 18 years, 9 months ago
Hello, It seems as though stl strings allocate memory on the heap behind the scenes, and keeps it there even if you are using temporary strings. For example, suppose you have a DLL and an APP. DLL: string EXPORT_MACRO foo() { return string( "pink lemonade" ); } APP: void bar( string str ) { cout << str << endl; } APP: bar( foo() ); /* BOOOM - exception thrown */ You would think that a variable that is returned by value, would be copied and thus be completely different than the original value in the function that was returned. Instead, in APP on bar( foo() ); it passes the temporary string returned from foo() to bar() and then when it's finished, it runs the temporary string's destructor, which then tries to delete memory from the heap which was allocated in the DLL - and thus the BOOOM. Is this correct? If so, why? And what is the best alternative? Thanks.
Advertisement
I suppose you could A) return a const char* from the DLL function, so that any creation of a string object will happen within the application, and never in the DLL, or you could B) use the multithreaded DLL version of the standard library, rather than any of the non-DLL versions. I'm not sure of how to do it on most compiles, but with VC6, I think (from memory) that it's in the project settings, under the C++ tab, under the code generation subsection. I think. You'd have to read the compiler's documentation, or ask less ignorant people regarding a specific compiler, if it's something else (or if I'm wrong about VC6; I don't have a copy available to verify).
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke
Quote:Original post by Agony
I suppose you could A) return a const char* from the DLL function, so that any creation of a string object will happen within the application, and never in the DLL, or you could B) use the multithreaded DLL version of the standard library, rather than any of the non-DLL versions. I'm not sure of how to do it on most compiles, but with VC6, I think (from memory) that it's in the project settings, under the C++ tab, under the code generation subsection. I think. You'd have to read the compiler's documentation, or ask less ignorant people regarding a specific compiler, if it's something else (or if I'm wrong about VC6; I don't have a copy available to verify).


I tried const char *, and the problem I found with that is that the temporary string in the DLL function gets removed before the new string in the app can be created with the char pointer. For example:

DLL EXPORT_MACRO const char *foo() { return string( "ant farm" ).c_str(); }

/* returned value is a pointer to the char data that was created on the heap - the string was just deleted when foo() was removed from the stack, so now the returned pointer points to undefined and invalid memory */

APP: bar( foo() ); /* BOOOM again */

I could create memory on the heap myself, but that would be a very bad design choice -> the app would have to tell the DLL to delete the memory after it's done with it, eek.

I'm not sure about multithreaded stl library, and why that would fix this problem, but thanks for a direction to look in.
Welp, it seems VC7.1 defaults to Multi-Threaded Debug (/MTd) for debug DLL projects. There goes that option. :/
Trying changing everything to Multi-Threaded Debug DLL.

The problem is that each executable and dll has it's own heap and free-store (std::string will allocate from the free-store by default).
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
though I have never bothered messing with them what I would suggest is reading up on allocators. AFAIK if you give your dll function an allocator that you make or get from the stl that comes from the origional program then you give that to your string then it will have a compatible way of using the heap. I would suggest reading about how to do that though as I dont know exactly how it would work.
ASCII stupid question, get a stupid ANSI
That worked like a charm, thanks! However, is there anything I should be concerned about with using multi-threaded DLL's specific to game programming? Thanks again!
Quote:Original post by Chris81
I tried const char *, and the problem I found with that is that the temporary string in the DLL function gets removed before the new string in the app can be created with the char pointer. For example:

DLL EXPORT_MACRO const char *foo() { return string( "ant farm" ).c_str(); }

/* returned value is a pointer to the char data that was created on the heap - the string was just deleted when foo() was removed from the stack, so now the returned pointer points to undefined and invalid memory */

APP: bar( foo() ); /* BOOOM again */

What I meant was something more like this:

EXPORT_MACRO const char *foo() { return "ant farm"; }
//Or to be safe, since I am unsure without testing whether that will work,
// though I'm guessing it should. (The string should be just a static
// part of the executable, thus no allocation/deallocation should be needed
EXPORT_MACRO const char *foo() { static const char FOO_STR[] = "ant farm"; return FOO_STR; }
Quote:Original post by Anonymous Poster
What I meant was something more like this:
"What I meant", as in "What I, Agony, meant". First time the darn logout has caught me in the middle of posting.
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke

This topic is closed to new replies.

Advertisement