Sign in to follow this  
Chris81

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

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
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; }

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this