Как использовать конструктор копирования с динамическим размещением?

У меня проблемы с упражнением для школы, в котором нам нужно использовать динамическое распределение для массива char и массива int. Главное, я не должен менять основную функцию и способ построения объектов.

class Automobile
{
 char* Name; //this is the name of the car that needs to be saved with dynamic alloc.
 int* Reg; //registration with dynamic alloc.
 int speed; //speed of the car
public:
Automobile(){ speed=0;}
Automobile(char* name,int* Reg,int speed)
{
    Name=new char[strlen(name)+1];
    strcpy(Name,name);
    Reg = new int[5];
    for(int i=0;i<5;i++)
    {
        this->Reg[i]=Reg[i];
    }
    this->speed=speed; //the normal constructor doesn't make any problems since it's called once
}
 Automobile(const Automobile& new)
 {
    Name= new char[strlen(new.Name)+1];
    strcpy(Name,new.Name);
    Reg=new int[5];
    for(int i=0; i<5; i++) Reg[i]=new.Reg[i];
    speed=new.speed;
}

 ~Automobile(){
    delete [] Name;
    delete [] Reg;
}
int main()
{
int n;
cin>>n;

for (int i=0;i<n;i++)
{
    char name[100];
    int reg[5];
    int speed;

    cin>>name;

    for (int i=0;i<5;i++)
        cin>>reg[i];

    cin>>speed;

    Automobile New=Automobile(name,reg,speed);

}

в основной функции объект New воссоздается (??) в цикле, поэтому вызывается конструктор копирования (я не уверен в этом). В конструкторе копирования я не удаляю память (должен ли я?), поэтому отладчик показывает мне, что есть проблема в строке, где я делаю Новая память для имени . Я попытался добавить delete [] Name и сохранить имя другого объекта во временном указателе, поэтому я могу повторно назначить имя временному, но это тоже не работает. Компилятор не показывает никаких ошибок, когда я его собираю, но страница, на которой я должен сохранить упражнение, показывает, что у меня есть bad_alloc (я не уверен, связано ли это с указатель копирования).


person Bonne    schedule 10.04.2015    source источник
comment
Вы на самом деле не должны называть свою переменную new, это ключевое слово C++.   -  person Cory Kramer    schedule 10.04.2015
comment
На самом деле это не называется новым, я просто изменил их имена на английском здесь, чтобы они были более понятными.   -  person Bonne    schedule 10.04.2015
comment
Вы должны внимательно прочитать это: Что такое правило трех.   -  person πάντα ῥεῖ    schedule 10.04.2015
comment
После переименования переменной new и добавления нескольких отсутствующих фигурных скобок ваш код компилируется и запускается. Что конкретно кажется проблемой?   -  person Igor Tandetnik    schedule 10.04.2015
comment
Вы также должны прочитать это: stackoverflow .com/questions/3279543/   -  person andre    schedule 10.04.2015
comment
Когда я запустил отладчик, он показал мне, что с конструктором копирования что-то не так, но если это не так, я действительно не знаю, где искать ошибку. Я тоже не понимаю, почему я получаю ошибку bad_alloc. (примечание: это только часть упражнения, некоторые части я удалил)   -  person Bonne    schedule 10.04.2015


Ответы (1)


Это, в конструкторе с тремя параметрами

Reg = new int[5];

присваивается параметру функции, а не члену.
Это оставляет член неинициализированным (потому что вы его не инициализируете), что приводит к тому, что ваше копирование массива записывается в случайное место, что может привести к сбою, а может и не к нему.< br> Если это не сработает, скорее всего, delete в деструкторе не сработает.

Хорошее исправление — не использовать повторно имена членов для чего-то другого в той же области (в данном случае переименовывать параметры).
Тогда оставлять this-> не только не катастрофа, но даже рекомендуется.

Вы также забыли инициализировать элементы указателя в конструкторе по умолчанию.

Примечание: канонический способ создания и инициализации объекта

Automobile New(name,reg,speed);
person molbdnilo    schedule 10.04.2015
comment
Когда я инициализирую их в конструкторе по умолчанию, я просто даю им значение NULL? - person Bonne; 10.04.2015
comment
@Bonne Вы можете сделать это, так как удалить нулевой указатель безопасно, но тогда вашему конструктору копирования необходимо проверить наличие нуля в оригинале, и вам, вероятно, потребуется проверить больше мест, если программа будет расти. Вероятно, проще указать имя на пустую строку или строку, не обозначающую имя, а Reg на недопустимую числовую последовательность. Или вы можете просто оставить конструктор по умолчанию. - person molbdnilo; 10.04.2015