   Confusing STL string crash
  Okay, this seems trivial and like it should work fine, but it doesn't entirely. I have a struct, used to store D3D adapter names:struct RendererDevices_s {int device;string DeviceName;};During initialization, I fill an array of these structures. In my main code I have:RendererDevices_s Devices[10];int count = renderLib->EnumDevices( Devices, 10 );and in my renderer DLL, within EnumDevices(), I have a loop which queries each device and fills the structure through a pointer, the relevant part of the loop being:RendererDevices.device = 0;RendererDevices.DeviceName = Adapter.DeviceName;For the most part, this works fine. The string DeviceName is being set to the char array returned by D3D, and it prints out properly. The problem is, when the program exits, I get an unhandled exception error. In a totally unrelated piece of code. If I remove that single line which assigns Adapter.DeviceName to the string, the program no longer crashes.My only thought is that the string is somehow overwriting memory used elsewhere, but this doesn't make any sense since I'm using a STL string to store it, which should eliminate this problem. Is there something I might be overlooking? Am I abusing the string in some way? I know I'm not overrunning the Devices array, since only a single device is being filled on my system. Any ideas?   
  Well, what exception was thrown, that wasn't handled?   ;  DLLs + std::string = Warning bells.Does everything work fine if you move the code from your DLL into your main application?   ;  Strange. Yes, moving that code from the DLL into the main code made the crash disappear. Here is the exception message I was getting when it crashed:Unhandled exception at 0x004e0651 in IxEngine.exe: 0xC0000005: Access violation reading location 0x00d76970.Which left me at a breakpoint within the STL (STLport) memory allocation code.Why is std::string bad in DLLs? How do DLLs change things? Is there something I can do to make it work?;  your application and your DLL have separate free stores. When the string is created in the DLL code, it allocates memory from the DLL's free store. Most STL implementations use reference counting for their string implementation. As a result, if the string is copied to a data structure in the application side, it will reference the string memory in the DLL's free store. If the DLL's reference is removed before the application's, the application will attempt to free memory that is not in its free store, and will throw an exception.The solution, I believe, is to use a special allocator that ensures memory is allocated and deallocated from only one source.   ;  Okay, that makes some sense... Though, considering that the structure containing the string variables were already in the application, and only referenced by the DLL through a function call pointer, does that mean there was some other background allocation going on in the DLL, like a copy constructor or something?In the end though, the function returns from the DLL, and the string is still in the application memory. So what was being left behind to cause the crash? Is it possible the application and DLL were both attempting to free the same string data when the program exited since they both referenced it?Or is it perhaps the dynamic size of the string object? The DLL copies a char array into the string, so the string buffer gets expanded to hold it. Though, running within the DLL, it gets expended with DLL memory. Is that possible? Is there a way to pre-allocate the string's buffer? Or is that just a hack?I'm just trying to understand *why* the problem is occuring, what could be going on, rather than just tiptoing around the issue. Thanks!   ;  Actually, the application and DLL may have the same free store and still have this kind of problem. The root problem is that template functions are implicitly inlined and when the calling environment of two related inline functions are different, you can have behavior mismatches. This kind of thing can happen even without DLLs, but since DLLs are an actual seperate executable module the environments are almost never the same between any two calls between the two. This is a somewhat vague, but the number of different ways that std::string can get screwed up between a DLL and the executable are essentially limitless.To reduce the chances of these problems happening, you need to do several things. First off, you have to make sure that the application using the DLL is compiled with the same compiler and standard library implementation (usually not a problem), then you have to make sure that both the application and the DLL share the C runtime. In MSVC this accomplished by building both EXE and DLL with the Multithreaded DLL version of the C Runtime, or the Multithreaded Debug DLL version of the C Runtime for a debug build. Then you need to make sure to export the template class from the DLL properly.  Here is an article describing the syntax necessary. Also if you use custom allocators, you have to make sure any static members of the allocators are exported properly too.Also, if you have multiple DLLs using the template classes, you should then either create a new DLL that the other DLLs use to import the template classes from, or otherwise mark one of the DLLs as holding the master copies of the template code.All in all, I personally prefer not to use template classes in my DLL interfaces.   ;  Damn, well isn't that a royal pain. :P I just did a little experimenting with the notes that you linked to, and got all sorts of problems from the fact that I'm using STLport and not the standard VC++ STL. I guess my best bet is to just not pass STL objects between my application and DLLs. Though that seems like a big limitation. So it's either no DLLs, or no STL string safety. Damn... Well, thanks for the insight!   ;Quote:Original post by NairouDamn, well isn't that a royal pain. :P I just did a little experimenting with the notes that you linked to, and got all sorts of problems from the fact that I'm using STLport and not the standard VC++ STL. I guess my best bet is to just not pass STL objects between my application and DLLs. Though that seems like a big limitation. So it's either no DLLs, or no STL string safety. Damn... Well, thanks for the insight!This is not a big limitation because you can create an adapter that will take a std::string as the argument and send the underlying const char* to the DLL:class Adaptor{  DllClass mClass;public:  bool someFunction(const std::string& s)  {return mClass.someFunction(s.c_str());  }};Your DLL is then still allowed to use std::string internally, but no std:string appear in your exported interface. The adaptor class is lightweight enough to be enterily inlined so that's not really a problem. Of course, it implies some additional design work, as well as some additional coding work (which might result in more bugs).Regards,   ;  Very good point, thanks for that. Though std::strings were only part of the bigger picture, I'm assuming these limitations would prevent passing things like std::vector references back and forth as well.   