none
Erreur sur delete pointeur RRS feed

  • Question

  • Bonjour a toutes tous.

    Je suis en cours de découverte du C++, j'ai appris qu'il faut détruire les pointeurs (delete)

    dans le code suivant :

    #include "stdafx.h"
    #include<iostream>
    using namespace std;
    
    class Test
    {
    public:
    	Test(int v1, int v2);
    	Test(Test const& copieC);
    	~Test();
    
    private:
    	int* ptrV1;
    	int* ptrV2;
    };
    
    Test::Test(int v1, int v2) {
    	ptrV1 = new int(v1);
    	ptrV2 = new int(v2);
    	cout << "ptrV1 : " << ptrV1 << " - ptrV2 : " << ptrV2 << endl;
    	cout << "v1    : " << v1 << " - v2    : " << v2 << endl;
    }
    
    Test::Test(Test const& copieC) {
    	ptrV1 = copieC.ptrV1;
    	ptrV2 = copieC.ptrV2;
    	cout << "Copie de Test\n";
    	cout << "*copieC.ptrV1 : " << *copieC.ptrV1 << " - *copieC.ptrV2 : " << *copieC.ptrV2 << endl;
    }
    Test::~Test() {
    	cout << "destructeur C\n";
    	delete ptrV1;
    	delete ptrV2;
    	ptrV1 = nullptr;
    	ptrV2 = nullptr;
    }
    
    
    int main()
    {
    	{
    		Test ctest(1, 5);
    		Test copieC(ctest);
    	}
    	int rep;
    	cin >> rep;
    	return 0;
    }

    Une ereur se déclenche lors de la destruction de la copie de la classe.

    L'erreur se déclenche dans le fichier delete_scalar.cpp ligne _free_dbg....

    void __CRTDECL operator delete(void* const block) noexcept
    {
        #ifdef _DEBUG
        _free_dbg(block, _UNKNOWN_BLOCK);
        #else
        free(block);
        #endif
    }
    Je ne vois pas d'où provient l'erreur, si vous pouviez me donné une piste, merci d'avance.

    Laurent


    mercredi 1 mars 2017 12:08

Réponses

  • Bonjour,

    Le problème est dans la seconde instance de Test.

    Test copieC(ctest);

    Dans copieC, les membres

    int* ptrV1;
    int* ptrV2;

    n'ont pas été initialisés par new ...

    Dans main, à la fin du bloc le destructeur Test::~Test est bien appelé pour chaque instance.
    Dans copieC le destructeur essaie de détruire ptrV1 et ptrV2 qui n'existe déjà plus.

    Cordialement

    Gérard

    • Proposé comme réponse GP79 mercredi 1 mars 2017 13:31
    • Marqué comme réponse Paul BacelarModerator mercredi 1 mars 2017 15:21
    mercredi 1 mars 2017 13:00

Toutes les réponses

  • Bonjour,

    Le problème est dans la seconde instance de Test.

    Test copieC(ctest);

    Dans copieC, les membres

    int* ptrV1;
    int* ptrV2;

    n'ont pas été initialisés par new ...

    Dans main, à la fin du bloc le destructeur Test::~Test est bien appelé pour chaque instance.
    Dans copieC le destructeur essaie de détruire ptrV1 et ptrV2 qui n'existe déjà plus.

    Cordialement

    Gérard

    • Proposé comme réponse GP79 mercredi 1 mars 2017 13:31
    • Marqué comme réponse Paul BacelarModerator mercredi 1 mars 2017 15:21
    mercredi 1 mars 2017 13:00

  • Dans copieC le destructeur essaie de détruire ptrV1 et ptrV2 qui n'existe déjà plus.

    Et on remercie la C-Runtime en Debugde nous avoir prévenue.

    C'est le genre de truc qui peut passer inaperçu sans le support d'outils "spéciaux".

    Vous parlez de pointeur nu sans faire mention des pointeurs intelligents.

    C'est donc que votre cours aborde les pointeurs nus avant les pointeurs intelligents (ou que les pointeurs nus). C'est donc un très mauvais et ou vieux cours qui utilise le C++ comme du "C with classes". Changez de cours au risque d'avoir à tout désapprendre pour coder correctement en C++.


    Paul Bacelar, Ex - MVP VC++

    mercredi 1 mars 2017 13:25
    Modérateur
  • Merci Gerard,

    Bien sur ! : pas de déclaration avec new dans le constructeur de copie...

    Avec ce code iil n'y as plus d'erreur :

    Test::Test(Test const& copieC) {
    	ptrV1 = new int(*copieC.ptrV1);
    	ptrV2 = new int (*copieC.ptrV2);

    Merci encore.


    Laurent


    mercredi 1 mars 2017 14:53
  • Merci Paul,

    oui je "connais" les pointeurs intelligent (unique_ptr ect.. ) mais le travail sur les pointeurs à la C m'interesse, je veux savoir comment cela fonctionne, donc j'étudis la 'chose'  ;o)

    Cordialement


    Laurent

    mercredi 1 mars 2017 14:57