Debug Assertion Failed! Expression: _pFirstBlock == pHead
Je suis remettre en statiquement .dll, et je vois ce message d'erreur:
J'ai écrit à la fois l' .dll et le code appelant. Cette erreur ne devrait pas se produire. Je me demandais si quelqu'un d'autre a rencontré avant? L' .dll contient seulement environ 10 lignes de code, c'est juste un test .dll afin de voir comment les dll de travail en général. Il explose quand je passe un std::string dos de la .dll.
Je suis à l'aide de Visual Studio 2012 et C++.
Ce que je vais essayer la prochaine
De Debug assertion... _pFirstBlock == pHead:
Ce problème peut se produire si l'on utilise le thread unique bibliothèques dans un
multithread module.
Demain, je vais essayer de recompiler le Boost de bibliothèques statiques en mode multithread (mon .dll est réglé sur multi-thread mode statique).
Ce que je vais essayer la prochaine
Vous avez besoin de faire une de deux choses
- Faire à la fois la DLL et le client qui l'utilisent à la fois le lien de la DLL version de la CRT (par ex. pas de manière statique).
- OU Vous devez vous assurer que vous ne passez pas la mémoire allouée dynamiquement (comme contenue dans les objets string) à travers des limites de la DLL.
En d'autres termes, n'ont pas de DLL-fonctions exportées que la chaîne de retour
objets.Joe
Cela semble correspondre à ce qui se passe, il souffle jusqu'au point précis où je passe une chaîne de retour dans une .dll limite. Le problème se produit uniquement lorsque tout est lié en mode statique. Maintenant que c'est réparable.
Voir Référence passant de vecteur STL sur dll limite.
Ce que je vais essayer la prochaine
Voir Incapables de passer à std::wstring à travers DLL.
Solution
J'ai une belle solution, voir la réponse ci-dessous.
- Et précisément ce qui est votre question?
- Il indique que vous avez des tas de corruption. Ce qui peut provoquer une corruption de segment de mémoire? Au moins un million de choses différentes. Si vous publiez certaines de code peut-être que quelqu'un peut vous aider.
- J'ai écrit à la fois l' .dll et le code appelant. Cette erreur ne devrait pas se produire. Je me demandais si quelqu'un d'autre a rencontré avant?
- Mais il est clair que se passe. Réclamez-vous que vous êtes incapable d'écrire le code qui endommage le tas?
- L' .dll contient seulement environ 10 lignes de code, c'est juste un test .dll pour voir comment il fonctionne.
- Même si vous pensez qu'il ne faut pas se produire, il est clairement. Donc, il y a 99,9% de chance il y a quelque chose de mal dans votre code...
- Puis afficher le code, et le code d'appel, si possible, tout
- Si vous voulez la recherche de choses vous-même, essayez de regarder à la ligne 1424 de dbgheap.c. Il peut vous donner des indices.
- à la simple évocation de l'erreur dans un moteur de recherche. Certains intéressant de frappe, par exemple, casablanca.codeplex.com/discussions/442262, "Que la trace de la pile est trop familier pour moi -- la mise en page de chaînes standard varient entre d'exécution des binaires pour les différentes configurations. Si j'étais un homme de pari, je serais prêt à parier que vous avez un mélange de release et debug binaires dans l'exécution de votre dossier." Aussi stackoverflow.com/questions/15524591/.... Essentiellement, il semble que vous pourriez avoir une disparité entre la façon dont votre exe et dll sont construits.
- Je pense que vous avez probablement raison. Je vais vérifier que les paramètres de mon .projet exe et .projet de dll sont pas différents.
- Cela s'est également produit lors du déplacement de Visual Studio 2015 et depuis Qt ne fournit pas les binaires Qt doit être construit à nouveau avec les bonnes options (Visual Studio compilateur)...
Vous devez vous connecter pour publier un commentaire.
Dans ce cas, le problème est que j'ai été en passant un
std::string
de retour dans une .dll limite.Bibliothèque d'exécution de config
Si le MSVC
Runtime library
est fixé àMulti-threaded Debug DLL (/MDd)
, alors ce n'est pas un problème (il fonctionne très bien).Si le MSVC
Runtime library
est fixé àMulti-threaded Debug (/MTd)
, puis il va se débarrasser de cette erreur, qui peut être résolu avec les instructions suivantes.Mémoire allouée dans le Gestionnaire de Mémoire A et libéré dans le Gestionnaire de Mémoire B ...
Le problème est que la mémoire est allouée sur la .dll côté, alors que même la mémoire est libérée sur le côté application. Cela signifie que le gestionnaire de mémoire est Un allouer de la mémoire, et la mémoire du gestionnaire de B est la libération de cette même mémoire, ce qui génère des erreurs.
La solution est de faire en sorte que toute la mémoire passé est pas allouée dans la DLL. En d'autres termes, la mémoire est toujours allouée sur le côté application, et libérée sur le côté application.
Bien sûr, le fichier DLL peuvent allouer/libre de la mémoire interne, mais il ne peut pas allouer de la mémoire, qui est ensuite libéré par l'application.
Exemples
Ce sera pas travail:
Cela fonctionne:
Cependant, ce n'est pas tout à fait assez.
Sur le côté application, la chaîne doit être pré-alloué:
Sur le .dll côté, le texte doit être copié dans le tampon d'origine (plutôt que remplacé par de la mémoire qui est allouée sur le .dll côté):
Parfois, C++ va insister sur l'allocation de la mémoire, de toute façon. Vérifiez que la pré-allocation est toujours le même qu'il était:
Une autre façon est d'utiliser
std::shared_ptr<std::string>
, donc, même si la mémoire est allouée dans le .dll, il est libéré par l' .dll (plutôt que sur le côté application).Encore une autre façon est d'accepter un
char *
et d'une longueur qui indique la quantité de pré-alloué de la mémoire. Si le texte que nous voulons transmettre est plus longue que la longueur de pré-alloué de la mémoire, une erreur est renvoyée.C'est ce que assert() ressemble quand son expression argument a la valeur false. Cette assertion existe dans la version de Débogage de la bibliothèque runtime C, conçu pour vérifier les problèmes d'allocation. Le free() fonction dans votre cas. La version Debug ajouter des contrôles assurez-vous d'écrire votre code correctement. Et vous dire quand il détecte un problème. Comme d'appeler free() sur une répartition qui a déjà été libéré, le cas simple. Ou appeler free() en passant le pointeur incorrect de la valeur, le plus délicat de cas. Ou appeler free() lorsque le tas a été corrompu par le code mentionné plus tôt, beaucoup plus dure.
Ce n'est qu'autant qu'ils peuvent prendre, ils ne le savent pas vraiment pourquoi votre code dans l'erreur. Il n'y a pas de toute façon, ils peuvent mettre une Grosse flèche Rouge sur le code qui a corrompu le tas, par exemple. Le cas simple est couvert par le Debug + Windows + de la Pile des Appels fenêtre du débogueur, il vous faut le code dans votre programme qui a appelé free(). Ou
std::operator delete
pour un programme C++. Le plus dure est très, très dur en effet, la corruption de segment est souvent un Heisenbug. L'obtention de la faire valoir pour être reproductible de sorte que vous pouvez définir un ensemble de données de point d'arrêt sur l'adresse signalée est la stratégie de base. Croise les doigts pour le cas simple, bonne chance avec elle!Après edit: oui, avoir de la croix-module de problèmes avec une classe C++ comme std::string est certainement l'un des problèmes qu'il peut attraper. Pas un Heisenbug, bon genre de problème à avoir. Deux questions fondamentales avec qui:
Le seul remède à ce problème est de s'assurer que vous construisez tous les modules dans votre programme avec la même version de compilateur en utilisant exactement les mêmes paramètres de construction. À l'aide de /MD est obligatoire, il s'assure que le CRT est partagé, donc il n'y a qu'un dans le programme.
La cause probable: la liaison à une mauvaise version de l'intervalle Qt Dll, surtout lorsque le déplacement d'un projet de VS2010 pour VS2012.
Cela est dû aux différentes versions de la bibliothèque standard et dynamique associée des questions de répartition.
J'ai eu le même problème après une réinstallation de Windows. Ma bibliothèque d'Exécution de construire a été multithread DLL de Débogage (
/MDd
).Ma solution a été de supprimer
*.user
fichier de projet visual studio, supprimer le dossier de débogage et de reconstruire le projet.