¡Depuración de aserción! Expresión: __acrt_first_block == encabezado

Estoy tratando de probar el dll que escribí con GoogleTest y cuando llamo a una de las pruebas Me arroja este error:

enter image description here

He llegado a la conclusión de que el problema está en asignar memoria a los vectores, pero no sé cómo resolver esto ya que soy bastante nuevo en la progtwigción en C ++. El código es el siguiente:

#ArraysCPP11.h #ifdef ARRAYSCP11_EXPORTS #define ARRAYSCP11_API __declspec(dllexport) #else #define ARRAYSCP11_API __declspec(dllimport) #endif __declspec(dllexport) void removeWhiteSpaces(std::vector v, std::vector &output); 
 #ArraysCPP11.cpp void removeWhiteSpaces(std::vector v, std::vector &output) { //odstranjevanje presledkov iz vector-ja (vsak drugi element je bil presledek) for (std::vector::iterator it = v.begin(); it != v.end(); it++) { std::string buffer = *it; if (isdigit(buffer[0])){; output.push_back(*it); } } } 
 #TestTemp.h template class TestTemp { public: TestTemp(); void SetValue(T obj_i); T GetValue(); bool alwaysTrue(); bool TestTemp::formattingTest(std::string input, std::vector realVector, std::vector formattedInput); private: T m_Obj; }; template inline bool TestTemp::formattingTest(std::string input, std::vector realVector, std::vector formattedVector) { std::string input2 = input; // std::vector fResult; std::string first; std::string second; bool endResult = true; std::vector end; //std::vector result = split(input2, ' '); removeWhiteSpaces(formattedVector,end); std::vector::iterator yt = realVector.begin(); for (std::vector::iterator it = end.begin(); it != end.end(); it++, yt++) { first = *it; second = *yt; if (first.compare(second) != 0) { endResult = false; break; } } return endResult; } 
  #ArraysCPP11-UnitTest.cpp struct formattingTesting{ // formattingTesting* test; std::string start; std::vector endResult; formattingTesting() { } explicit formattingTesting(const std::string start, const std::vector endResult) : start{start}, endResult{endResult} { } }; struct fTest : testing::Test { formattingTesting* test; fTest() { test = new formattingTesting; } ~fTest() { delete test; } }; struct format { std::string start; std::vector end; }; struct formTest : fTest, testing::WithParamInterface { formTest() { test->start = GetParam().start; test->endResult = GetParam().end; } }; TEST_P(formTest, test1) { bool endResult = true; TestTemp TempObj; std::string first; std::string second; //std::string start ("1 2 3 4 5 6 7 8 9 10"); //std::vector end = { "1","2","3","4","5","6","7","8","9","10" }; std::vector start2 = { "1","","2","3","4","5","6","7","8","9","10" }; std::string start = GetParam().start; std::vector end = GetParam().end; bool result = TempObj.formattingTest(start,end,start2); EXPECT_TRUE(result); } INSTANTIATE_TEST_CASE_P(Default, formTest, testing::Values( format{ "1", {"1"} }, format{ " ", {} }, format{ "1 2 3 4 5",{"1","2","3","4","5"} }, format{ "1 2 3 4 5 6", {"1","2","3","4","5","6"} } )); int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); RUN_ALL_TESTS(); return 0; } 

Como se trata de una DLL, el problema podría residir en montones diferentes utilizados para la asignación y la desasignación (intente construir la biblioteca estáticamente y verifique si eso funciona).

El problema es que las DLL y las plantillas no concuerdan muy bien. En general, dependiendo de la vinculación del tiempo de ejecución de MSVC, podría ser un problema si la memoria se asigna en el ejecutable y se desasigna en el archivo DLL y viceversa (porque pueden tener diferentes montones). Y eso puede suceder con las plantillas muy fácilmente, por ejemplo: push_back () al vector dentro de removeWhiteSpaces () en la DLL, por lo que la memoria del vector se asigna dentro de la DLL. Luego usa el vector de salida en el ejecutable y una vez que se sale del scope, se desasigna, pero dentro del ejecutable cuyo montón no sabe nada sobre el montón al que se le ha asignado. Bang, estás muerto.

Esto se puede solucionar si tanto DLL como el ejecutable usan el mismo montón. Para garantizar esto, tanto el DLL como el ejecutable deben usar el tiempo de ejecución dynamic de MSVC, así que asegúrese de que ambos se vinculen al tiempo de ejecución de forma dinámica, no estática. En particular, el exe debe comstackrse y vincularse con / MD [d] y la biblioteca con / LD [d] o / MD [d] también, ninguno con / MT [d]. Tenga en cuenta que posteriormente la computadora que ejecutará la aplicación necesitará la biblioteca de tiempo de ejecución de MSVC para ejecutarse (por ejemplo, instalando “Visual C ++ Redistributable” para la versión particular de MSVC).

Podrías obtener ese trabajo incluso con / MT, pero eso es más difícil: necesitarías proporcionar alguna interfaz que permita que los objetos asignados en la DLL también sean desasignados allí. Por ejemplo, algo como:

 __declspec(dllexport) void deallocVector(std::vector &x); void deallocVector(std::vector &x) { std::vector tmp; v.swap(tmp); } 

(sin embargo, esto no funciona muy bien en todos los casos, ya que debe llamarse explícitamente para que no se llame, por ejemplo, en caso de excepción; para resolver esto correctamente, debería proporcionar alguna interfaz desde el archivo DLL, que cubrirá el vector debajo del capó y se ocupará de la RAII adecuada)


EDITAR : la solución final era en realidad tener todos los proyectos (el exe, dll y todo el proyecto googleTest) integrados en la DLL de depuración de subprocesos múltiples (/ MDd) (los proyectos de GoogleTest se crean en la depuración de subprocesos múltiples (/ MTd) ) por defecto)

Tuve un problema similar y resultó que mi proyecto unittest se estableció en una biblioteca de tiempo de ejecución de generación de código diferente, por lo que al establecerlo igual que el proyecto DLL, entonces no hay excepción de montón

Estaba viendo este error también y en mi caso tenía todos los ajustes del modelo de memoria alineados correctamente. Sin embargo, habiendo actualizado recientemente los proyectos de vs2013 a vs2015, tenía referencias obsoletas entre .exe y .dll, así que de hecho estaba usando la antigua DLL creada con 2013. Tuve que eliminar la referencia entre .exe y .dll y re -agregó para actualizar el nombre de la .lib con la que el exe estaba enlazando. (Haga clic con el botón derecho en el elemento secundario “Referencias” del proyecto .exe y “Agregar”, aunque de manera confusa también le permite eliminar una referencia).