Debug Assertion Failed! Expression: __acrt__bloc == en-tête
Je suis en train de tester la dll que j'ai écrit avec GoogleTest et quand j'ai appeler l'un de ces tests, Il me lance ce message d'erreur:
Je suis venu à la conclusion que le problème est dans l'attribution de la mémoire à des vecteurs mais je ne sais pas comment résoudre ce que je suis assez nouveau à la programmation en C++. Le code est comme suit:
#ArraysCPP11.h
#ifdef ARRAYSCP11_EXPORTS
#define ARRAYSCP11_API __declspec(dllexport)
#else
#define ARRAYSCP11_API __declspec(dllimport)
#endif
__declspec(dllexport) void removeWhiteSpaces(std::vector<std::string> v, std::vector<std::string> &output);
#ArraysCPP11.cpp
void removeWhiteSpaces(std::vector<std::string> v, std::vector<std::string> &output) { //odstranjevanje presledkov iz vector-ja (vsak drugi element je bil presledek)
for (std::vector<std::string>::iterator it = v.begin(); it != v.end(); it++) {
std::string buffer = *it;
if (isdigit(buffer[0])){;
output.push_back(*it);
}
}
}
#TestTemp.h
template<class T>
class TestTemp
{
public:
TestTemp();
void SetValue(T obj_i);
T GetValue();
bool alwaysTrue();
bool TestTemp<T>::formattingTest(std::string input, std::vector<std::string> realVector, std::vector<std::string> formattedInput);
private:
T m_Obj;
};
template<class T>
inline bool TestTemp<T>::formattingTest(std::string input, std::vector<std::string> realVector, std::vector<std::string> formattedVector) {
std::string input2 = input;
// std::vector<std::string> fResult;
std::string first;
std::string second;
bool endResult = true;
std::vector<std::string> end;
//std::vector<std::string> result = split(input2, ' ');
removeWhiteSpaces(formattedVector,end);
std::vector<std::string>::iterator yt = realVector.begin();
for (std::vector<std::string>::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<std::string> endResult;
formattingTesting() {
}
explicit formattingTesting(const std::string start, const std::vector<std::string> 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<std::string> end;
};
struct formTest : fTest, testing::WithParamInterface<format> {
formTest() {
test->start = GetParam().start;
test->endResult = GetParam().end;
}
};
TEST_P(formTest, test1) {
bool endResult = true;
TestTemp<int> TempObj;
std::string first;
std::string second;
//std::string start ("1 2 3 4 5 6 7 8 9 10");
//std::vector<std::string> end = { "1","2","3","4","5","6","7","8","9","10" };
std::vector<std::string> start2 = { "1","","2","3","4","5","6","7","8","9","10" };
std::string start = GetParam().start;
std::vector<std::string> 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;
}
Vous avez undefined behavior dans votre code. Vous avez une chaîne vide dans le
le vecteur
Btw. pourquoi avez-vous copier les vecteurs partout au lieu de les passer par référence const (par exemple dans
Bien faire des commentaires sur votre exemple de ce que je comprends (je suis très débutant en C++) j'ai fait la fonction de travail de sorte que le vecteur
Le point est que vous pouvez utiliser
start2
vecteur, que vous passer à la removeWhiteSpace
fonction, d'où vous avez accès au premier caractère de la chaînes dans le vecteur. Si une chaîne est vide, il n'a pas un premier caractère, si vous êtes d'indexation en dehors des limites. Aussi le nom removeWhiteSpace
n'est pas très bonne, comme la fonction n'est pas réellement supprimer les espaces blancs, il vérifie juste si le premier caractère d'une chaîne est un chiffre ou pas (à tort, comme je viens de le remarquer).le vecteur
start2
est principalement utilisé pour le débogage de la comparaison de la partie de l'épreuve (la partie du code qui est, après l'appel des removeWhiteSpaces
) et sera supprimée après j'ai corrigé le problème. Aussi la fonction removeWhiteSpaces
en fait de supprimer l'espace blanc car il pousse uniquement les éléments qui sont des chiffres dans un nouveau vecteurBtw. pourquoi avez-vous copier les vecteurs partout au lieu de les passer par référence const (par exemple dans
removeWhiteSpaces(std::vector<std::string> v, ...)
où vous regardez seulement le vecteur v de sorte qu'il n'a pas besoin d'être non-const).Bien faire des commentaires sur votre exemple de ce que je comprends (je suis très débutant en C++) j'ai fait la fonction de travail de sorte que le vecteur
v
est une entrée et la fonction repousse les valeurs qui sont des chiffres dans le vecteur output
. Je sais qu'il y a probablement une meilleure façon de traiter avec cela, mais je n'ai pas vraiment trouvé une, si tout conseil serait grandement appréciéLe point est que vous pouvez utiliser
void removeWhiteSpaces(const std::vector<std::string> & v, std::vector<std::string> &output);
de ne pas copier le premier vecteur, et l'utilisation std::vector<std::string>::const_iterator
au lieu de std::vector<std::string>::iterator
à l'intérieur). Similaires pour d'autres fonctions avec des paramètres d'entrée qui n'ont pas besoin d'être modifié à l'intérieur.OriginalL'auteur Rok | 2016-02-10
Vous devez vous connecter pour publier un commentaire.
Que c'est une DLL, le problème pourrait résider dans différents tas utilisé pour l'allocation et la libération (essayez de construire la bibliothèque statique et vérifier si cela fonctionne).
Le problème, c'est que les Dll et les modèles ne sont pas d'accord très bien ensemble. En général, selon le lien de la MSVC de l'exécution, il peut être un problème si la mémoire est allouée dans le fichier exécutable et libérés dans la DLL et vice versa (parce qu'ils pourraient avoir différents tas). Et cela peut arriver avec des modèles très facilement, par exemple: vous push_back() pour le vecteur à l'intérieur de la removeWhiteSpaces() dans la DLL, de sorte que le vecteur de la mémoire est allouée à l'intérieur de la DLL. Ensuite, vous utilisez le vecteur de sortie dans le fichier exécutable et une fois qu'il est hors de portée, il est libéré, mais à l'intérieur de l'exécutable dont le tas ne sait rien sur le tas, il a été alloué. D'un coup, vous êtes mort.
Cela peut être travaillé si les deux DLL et le fichier exécutable utiliser le même tas. Pour ce faire, à la fois la DLL et le fichier exécutable doit utiliser la dynamique MSVC à l'exécution, alors assurez-vous que le lien vers le moteur d'exécution de manière dynamique, et non statique. En particulier, l'exe doit être compilé et lié avec /MD[d] et la bibliothèque avec /LD[d] ou /MD[d] ainsi, ni l'un avec l' /MT[d]. Notez que par la suite l'ordinateur qui exécute l'application aura besoin de la MSVC de la bibliothèque d'exécution pour exécuter (par exemple, par l'installation de "Visual C++ Redistributable" pour le particulier MSVC version).
Vous pouvez obtenir ce travail même avec /MT, mais ce qui est plus difficile - vous devez fournir une interface qui permettra de les objets alloués dans le DLL à être libéré. Par exemple quelque chose comme:
(toutefois, cela ne fonctionne pas très bien dans tous les cas, que ce doit être appelée explicitement de sorte qu'il ne sera pas appelé par exemple dans le cas de l'exception - pour résoudre cela, vous devez fournir une interface à partir de la DLL, ce qui va couvrir le vecteur sous le capot et prendra en charge le bon RAII)
MODIFIER: la solution finale a été fait a été de disposer de tous les projets (exe, dll et l'ensemble de la googleTest projet) construit en multithread DLL de Débogage (/MDd)
(le GoogleTest projets sont construits en Multi-thread de débogage(/MTd) par défaut)
Mise à jour de la réponse, en gros, vous avez besoin de lier l'encontre de la dynamique de l'exécution pour éviter ce genre de problèmes.
donc, si je comprends correctement, j'ai besoin de la bibliothèque d'exécution de l'exe pour /MD et l'un des DLL /LD droit? Si oui, je ne peux pas vraiment le faire pour la DLL en raison de la /LD option n'est pas donné à moi
Hum ... je pense que vous pouvez utiliser /MD pour la bibliothèque ainsi, la /LD fournit supplémentaire automatique des définitions de macros autant que je sache (c'est peut être supprimé dans les versions plus récentes, je ne le vois pas dans MSVC 2013)
Bien la construction de l'exe dans /MD résultats en moi un tas d'erreurs d'édition de liens (j'ai été la construction dans /MT jusqu'à maintenant et il a été bullt correctement)
OriginalL'auteur axalis
J'ai eu un problème similaire et il s'est avéré que mon unittest projet a été définie à une autre génération de code de la bibliothèque d'exécution - donc, en le définissant par la même que le projet de DLL, alors pas de tas exception
OriginalL'auteur serup
J'ai vu cette erreur de trop et dans mon cas, j'ai eu tous les modèles de mémoire les paramètres correctement alignés. Toutefois, après avoir récemment mis à jour les projets de vs2013 à vs2015 j'avais rassis références entre les .exe et .dll, donc en fait j'ai été en utilisant l'ancienne DLL construit avec 2013. J'ai dû supprimer la référence entre les .exe et .dll et l'ajouter à nouveau à mettre à jour le nom de la .lib que le fichier exe a été de se lier à des. (Clic droit sur le "Références" enfant " de la .projet exe et "Ajouter", tandis que de prêter à confusion, vous permet également de supprimer une référence).
OriginalL'auteur fret