Память для вектора выделяется в DLL и освобождается в exe, поскольку вектор, вероятно, использует в своем возвращении семантику перемещения (или даже просто RVO), которая просто перемещает указатель на выделенные внутренние компоненты. Поскольку вы используете статический ЭЛТ, это означает, что память распределяется с одним КРТ и освобождается с другим экземпляром, что приводит к ошибкам.
Короткая история - не делай этого. Экспонировать объекты C ++ через границы DLL - это плохо. Вы должны использовать интерфейс C или интерфейс, который предназначен для этого - например, WinRT.
Если вы решите выставлять объекты c ++ через интерфейс DLL, вы должны убедиться, что как EXE, так и DLL используют одну и ту же версию компилятора, и вы связываетесь с / MD. Если вы не можете использовать / MD, вы никогда не получите надежную работу.
Конечно, вы можете предварительно выделить вектор и заполнить его в вызове, но это только маскирует проблему, пока все неизбежно не изменится.