Un membre vecteur est réinitialisé et inaccessible

J’ai deux projets, un client de base et une bibliothèque dynamic. Voici ce qui se passe chez le client:

int main() { Scrutinizer scru; scru.Scrutinize(); return 0; } 

Dans la DLL, la classe Scrutinizer est en tant que telle (__declspec (dllexport) et telle omise pour Clarity)

Entête

 class ProcessesGenerator; class Scrutinizer { public: Scrutinizer(); ~Scrutinizer(); ProcessesGenerator *ProcGenerator void Scrutinize(); }; 

La déclaration ProcessesGenerator de ProcessesGenerator était «obligatoire» pour éviter toute sorte de référence circulaire.

Constructeur dans un fichier .cpp

Voici comment je l’initialise:

 Scrutinizer::Scrutinizer() { ProcGenerator = &ProcessesGenerator(); } 

En savoir plus sur cette classe ProcessesGenerator :

Entête

 class ProcessesGenerator { public: ProcessesGenerator(); ~ProcessesGenerator(); WinFinder winFinder; std::vector fooCollec; void GenerateProcesses(); }; 

ProcessusGenerator.cpp

Constructeur:

 ProcessesGenerator::ProcessesGenerator() { //winFinder = WinFinder();//problem will be the same with or without this line fooCollec = std::vector{"one", "two", "three"}; } 

Un point d’arrêt dans le constructeur indique que le vecteur est initialisé avec les valeurs choisies.

Fonction problématique:

 void ProcessesGenerator::GenerateProcesses() { std::ssortingng foo = "bar"; fooCollec = std::vector{};//read access violation fooCollec.push_back(foo);//read access violation winFinder.SomeVector= std::vector{};//read access violation } 

Une fois là, je peux voir que la taille du vecteur est réinitialisée à 0. Toute tentative de réinitialisation ou d’insertion d’un élément entraîne une violation d’access en lecture .Same avec le membre vecotr de son membre WinFinder . Je suppose que la faille est évidente, mais je ne comprends vraiment pas,

Merci!

Votre problème est avec

 Scrutinizer::Scrutinizer() { ProcGenerator = &ProcessesGenerator(); } 

Ce que vous faites, c’est prendre l’adresse d’un object temporaire. Cet object sera détruit et la fin de cette ligne et vous restra avec un pointeur qui ne pointe pas vers un object valide.

L’ancienne façon de le réparer serait d’utiliser

 Scrutinizer::Scrutinizer() { ProcGenerator = new ProcessesGenerator(); } 

Mais maintenant, vous devez implémenter le constructeur de copie, l’opérateur d’affectation de copie et le destructeur. Puisque vous avez un compilateur moderne, vous pouvez plutôt transformer ProcGenerator une ProcGenerator std:unique_ptr , puis Scrutinizer() devient

 Scrutinizer::Scrutinizer() : ProcGenerator(make_unique()) {} 

Je voudrais aussi append que &ProcessesGenerator(); ne devrait même pas comstackr. Malheureusement, MSVS a une extension non standard qui permet cette compilation. Vous pouvez activer l’option du compilateur /Za (appliquer la compatibilité ANSI) et vous obtiendrez alors une erreur telle que

erreur C2102: ‘&’ requirejs la valeur l

La ligne ProcGenerator = &ProcessesGenerator(); crée un ProcessesGenerator temporaire, prend son adresse puis la place dans votre pointeur ProcGenerator . Le temporaire est ensuite détruit, laissant des ordures.

Vous souhaitiez probablement l’allouer sur le tas ProcGenerator = new ProcessesGenerator; mais même dans ce cas, je suggérerais fortement d’utiliser unique_ptr au lieu d’un pointeur brut.