Linking the library in release and .exe in debug crashes in Visual Studio

I am using Visual C ++ 2008 SP1. I have an application that compiled in debug mode, but links to the library in release mode.

I get crash on application launch. To reduce the problem, I created a simple solution with two projects:

  • lib_release (generates .lib, in release mode)
  • exec_using_lib_release (genereates.exe, in debug mode)

The lib_release project is simple enough to have a simple class:

//Foo.h #include <vector> class Foo { std::vector<int> v; public: void doSomething(); }; //Foo.cpp #include "Foo.h" void Foo::doSomething() {} 

The exec_using_lib_release project is simple:

 //main.cpp #include "Foo.h" int main() { Foo foo; foo.doSomething(); return 0; } 

And it crashes, this is the same problem that is reported How do you create debug.exe (MSVCRTD.lib) against the released lib (MSVCRT.lib)? but his answer did not help me.

I get the same linker warnings, I tried the same steps, but no one worked. Is something missing?

EDIT:

In lib_release (which creates the library in release mode) I use Multi Threaded (/ MT), and in exec_using_lib_release I use Multi Threaded Debug (/ MTd). I think this is the expected way to do this, since I want .lib to be created without debugging information. I read the document in the MSDN Runtime library , and these are the settings for linking to a CRT in a static way.

I do not have "Common Language Runtime Support".

+6
c ++ visual-studio-2008 visual-studio linker
source share
4 answers

You don’t need to use the same time intervals for release and debugging modules (but this helps) if you follow very specific rules: never mix or match access to memory allocated using each runtime.

To make this easier, if you have a routine in the dll that allocates some memory and returns it to the caller, the caller should not free it - you must create a function in the original dll that frees memory. Thus, you are not sure about the runtime mismatch.

If you think that Windows DLLs are built only release (if you do not have a debug version of Windows), but you use them from debugging applications, you will see how it matters.

Now the problem is that you are using a static library, there is no longer a dll border, and calls to lib are compiled using the static version of the C runtime. If your exe uses the dynamic version of the runtime version, you will find that the linker is using the one and not the one used by your static lib ... and you will get crashes.

So you can rebuild your library as a dll; or you can make sure that both of them use the same CRT library; or you can make sure that both of them use the same type of CRT - that is, the dll version or the static version, while maintaining the differences in debugging / release.

At least I think this is your problem - what are the settings for "code generation, runtime"?

+8
source share

To combine the release and debugging issues that people have talked about before, these issues will not appear until the wrong runtime library tries to unselect. I think that you are faced with the fact that VS 2008 disables debugging of the iterator by default, therefore your library and your exe refer to different implementations of std :: vector. You need to add _HAS_ITERATOR_DEBUGGING = 0 to the preprocessor settings. Then you will start to face the problem of different heaps for different periods of time. In the past, we had different rules and policies to avoid this, but now we just rely on a consistent build environment β€” don't mix and match.

+5
source share

The problem is that debug will use the debug version of the c-runtime, and the release will use the release version of the c-runtime, and when you try to access memory through the dll border, it will be in the wrong runtime and crash. Its all ways best to use only debug builds together (or release)

+2
source share

A nested library should not share CRT resources across the library boundary. For C code, dynamically allocated memory must be freed on the same side of the boundary. For C ++ code, you can use the std namespace inside your DLL, but those objects that use the std namespace must be passed across the library boundary.

see this answer to a similar question

0
source share

All Articles