2014-10-16 3 views
-4

Я пытаюсь с нескольких дней сделать этот маленький код, но он не работает. Я вижу много вопросов об этой проблеме, но я не нашел ответа на свой вопрос.Ошибка: двойная свобода или коррупция (fasttop)

Вот код для Voiture.cpp:

#include <iostream> 
using namespace std; 
#include <string.h> 
#include "modele.h" 

Voiture::Voiture() 
{ 
Nom=NULL; 
setNom("Default"); 
VoitChoix=Modele(); 
cout << "COnstructeur default" << endl; 
} 

Voiture::Voiture(const char* N,const Modele V) 
{ 
Nom=NULL; 
setNom(N); 
setModele(V); 
cout << "COnstructeur initialisation" << endl; 
} 

Voiture::Voiture(const Voiture& V) 
{ 
Nom=NULL; 
setNom(V.getNom()); 
setModele(V.getModele()); 
cout << "COnstructeur copie" << endl; 
} 
Voiture::~Voiture() 
{ 
if(Nom) 
{ 
    cout << "Voiture : Destruction de" << Nom << endl; 
    delete [] Nom; 
} 
}  

Вот код для Modele.cpp:

#include <iostream> 
#include <string.h> 
using namespace std; 
#include "modele.h" 

Modele::Modele() 
{ 
Nom=NULL; 
setNom("Default"); 
Puissance=0; 
Diesel=true; 
PrixDeBase=0; 
cout << "COnstructeur default" << endl; 
} 
Modele::Modele(const char* N,const int P,const bool D,const float PDB) 
{ 
Nom=NULL; 
setNom(N); 
setPuissance(P); 
setDiesel(D); 
setPrixDeBase(PDB); 
cout << "COnstructeur initialisation" << endl; 
} 
Modele::Modele(const Modele& M) 
{ 
Nom=NULL; 
setNom(M.getNom()); 
setPuissance(M.getPuissance()); 
setDiesel(M.isDiesel()); 
setPrixDeBase(M.getPrixDeBase()); 
cout << "COnstructeur copie" << endl; 
} 

Modele::~Modele() 
{ 
if(Nom) 
{ 
    cout << "Modele: Destruction de" << Nom << endl; 
    delete [] Nom; 
} 
} 

Вот код main.cpp:

int main() 
{ 
cout << "(1) ***** Test du constructeur par defaut de Voiture *****" << endl; 
{ 
Voiture voiture; 
voiture.Affiche(); 
} 
} 

Я не ставил весь код, где у меня проблема.

Спасибо! :(

+0

Вы также должны предоставить определение классов, так что мы можем по крайней мере видеть типы данных класса. – antred

+0

Я * думаю * Я заметил проблему (или хотя бы одну из проблем) в вашем коде. В конструкторе копирования вашего класса Modele вы присваиваете значение указателя Nom исходного экземпляра указателю Nom вашего нового экземпляра (по крайней мере, я подозреваю, что это то, что делает ваш метод setNom). После этого указатели Nom как исходного экземпляра, так и нового экземпляра будут указывать на один и тот же массив, и при их уничтожении попытается удалить один и тот же массив. Вы можете исправить это, сделав свой член Nom типа std :: string вместо использования динамически выделенного массива символов. – antred

+0

Измените свой код так, чтобы он был правильно отступом. Все покраснело на левое поле, что затрудняет чтение вашего кода. – PaulMcKenzie

ответ

1

Одна очевидная проблема заключается в том, что вам не хватает определенного пользователем оператора присваивания:.

VoitChoix=Modele(); 

Это вызывает оператор присваивания, а не конструктор копирования Поскольку вы не оператор присваивания, определенный пользователем для Modele, то у вас будут проблемы по уничтожению VoitChoix. Более конкретно, вы назначаете все значения, которые Modele() создал для VoitChoix.

Так у вас есть два экземпляра, которые имеют одинаковое значение указателя для Nom. Когда T emporary Modele() выходит за пределы области действия, он называет деструктор, удаляя Nom. Когда VoitChoix выходит из области действия, он попытается удалить то же значение указателя для Nom. Таким образом, двойная ошибка удаления.

Заданный оператор присваивания пользователя для Modele будет иметь следующий вид:

Modele& operator=(const Modele&); 

Вам необходимо будет выполнять эту функцию перед тем как двигаться дальше. Это можно легко сделать с помощью copy/swap идиомы: What is the copy-and-swap idiom?

Кроме того, пожалуйста, следуйте правилу трех при создании класса: What is The Rule of Three?

+0

Спасибо за ваш ответ всем, это мне очень помогает! –

Смежные вопросы