2 votes

Démonstration du constructeur de copie (plantage... cas 2)

Jetez un coup d'œil à ce programme :

class CopyCon
{
public:
char *name;

CopyCon()
{ 
    name = new char[20];        
    name = "Hai";//_tcscpy(name,"Hai");
}

CopyCon(const CopyCon &objCopyCon)
{
    name = new char[_tcslen(objCopyCon.name)+1];
    _tcscpy(name,objCopyCon.name);
}

~CopyCon()
{
    if( name != NULL )
    {
        delete[] name;
        name = NULL;
    }
}
};

int main()
{
    CopyCon obj1;
    CopyCon obj2(obj1);
    cout<<obj1.name<<endl;
    cout<<obj2.name<<endl;
}

Ce programme se bloque à l'exécution. Erreur : "Expression : _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)"

Si j'assigne "Hai" au nom en utilisant l'opérateur d'alignement, il se bloque. Alors que lorsque j'utilise le func string _tcscpy pour assigner "Hai" au nom, il fonctionne parfaitement. Quelqu'un peut-il m'expliquer pourquoi ?

4voto

aJ. Points 17014
 name = "Hai";//_tcscpy(name,"Hai");

Tu ne copies pas le contenu de "Hai" dans name au lieu de name pointera vers une mémoire en lecture seule ( dont le contenu est "Hai") si vous essayez de supprimer le nom plus tard, il pourrait crash.

3voto

sharptooth Points 93379

Dans le constructeur par défaut

CopyCon()
{ 
    name = new char[20];        
    name = "Hai";//_tcscpy(name,"Hai");
}

vous assignez l'adresse d'une chaîne littérale au pointeur et dans le destructeur vous appelez delete[] sur elle, c'est un comportement non défini. delete[] ne doit être appelé que sur les adresses renvoyées par new[] .

Si vous utilisez plutôt _tcscpy() vous copiez le contenu littéral dans le tampon alloué par new[] et ensuite le destructeur fonctionne bien.

2voto

Quand vous utilisez l'affectation, vous faites en sorte que le pointeur name pointe sur la chaîne littérale "Hai". Celle-ci sera ensuite supprimée dans le destructeur. Cependant, la chaîne littérale n'a pas été allouée avec la commande new et ne peuvent pas être supprimés de cette manière, ce qui entraîne un comportement indéfini. Vous pouvez seulement désallouer avec delete les choses que vous avez attribuées avec new . Cela n'a rien à voir avec le constructeur de copie.

2voto

Naveen Points 37095
name = new char[20];        
name = "Hai";//_tcscpy(name,"Hai");

Vous êtes ici no en copiant les données dans la mémoire allouée par new . Au lieu de cela, vous attribuez une nouvelle valeur au pointeur name qui pointe vers un emplacement en lecture seule (dans la plupart des cas). Puisque cette mémoire n'a pas été allouée en utilisant new vous ne pouvez pas faire delete sur elle. Notez également que vous avez une fuite de mémoire ici, car la mémoire allouée à l'aide de la fonction new char[20]; n'est jamais supprimée.

2voto

Matthieu M. Points 101624

Le même programme, mais en C++ :

struct CopyCon
{
  CopyCon(): name("HAI") {}
  std::string name;
};

int main(int argc, char* argv[])
{
  CopyCon obj1;
  CopyCon obj2(obj1);
  cout<<obj1.name<<endl;
  cout<<obj2.name<<endl;
}

Le mien fonctionne, est clair, et j'ai tapé moins que vous ;)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X