When you build with /MT[d], every module (EXE and DLL) contains its own copy of the C runtime, and in particular of the heap manager. One heap manager doesn't know what to do with a pointer allocated by another - from the first manager's point of view, it's just some random address.
When you build with /MD[d], all modules share the same copy of C runtime DLL, and all use the same heap manager.
This consideration applies to other resources (e.g. fopen
in one module and fclose
in another won't work with /MT)
It's best not to spread resource management across modules: if the DLL provides a function for allocating memory, have it also provide a function that the EXE could call to deallocate it later. Otherwise, you have to ensure that all modules are built by the same compiler version, the same settings (e.g. Debug vs Release) and all use C runtime DLL (so /MD or /MDd).