Программа останавливается - переместить массив в функцию | C ++ - PullRequest
0 голосов
/ 13 апреля 2019

У меня есть 2 класса. Первый класс - Midgam - Конструктор имеет следующую строку:

midgam = new Vector[20];

Второй класс - Vector - где я создаю массив с именем array.

Программа отлично работает, просто у меня небольшая проблема.

В конце программы я пытаюсь печатать в алфавитном порядке, использую сортировку BubbleSort. Сортировка работает нормально, но что-то в функции Swap останавливается.

Вот как это выглядит:

void Midgam::Swap(Vector *xp, Vector *yp) {
    Vector temp = *xp;
    cout << temp.getName() << endl;
    *xp = *yp;
    *yp = temp;
}

void Midgam::bubbleSort() {
    int i, j;
    for (i = 0; i < iterator - 1; i++) {
        for (j = 0; j < iterator - i - 1; j++) {
            if (midgam[j].getName().compare(midgam[j+1].getName()) > 0) {
                Swap(&midgam[j], &midgam[j+1]);
            }
        }
    }
}

Я работаю с Visual Studio, программа останавливается, и программа показывает мне следующий фрагмент кода в классе Vector:

Vector::~Vector() {
if (array)
        delete[] array;
}

полные определения Midgam :

#include <iostream>
#include <string>
#include "Vector.h"

using namespace std;

#ifndef MIDGAM_H_
#define MIDGAM_H_

class Midgam {
private:
    int boxNum;
    int maxParties;
    int iterator;
    Vector *midgam;
public:
    Midgam(int num_of_boxes, int num_of_parties);
    virtual ~Midgam();
    void Start();
    void Menurmal();
    void SumOfEzor();
    double SumOfParty(string name);
    int SumAllVotes();
    void AddParty();
    void Swap(Vector *xp, Vector *yp);
    void bubbleSort();
    void Histograma();
    void PrintStars(int num);
    int FindPartyByName(string party);
    void PrintAll();
};

#endif /* MIDGAM_H_ */

полные определения Vector :

#include <iostream>
#include <string>
#include <sstream>

using namespace std;

#ifndef VECTOR_H_
#define VECTOR_H_

class Vector {
private:
    string name;
    int size;
    unsigned int *array;
    bool Bool;
public:
    Vector(string name, int size);
    Vector();
    Vector & operator=(const Vector &);
    virtual ~Vector();
    bool StringToArray(string str);
    bool getBool();
    string getName();
    unsigned int getAddress();
    int getSize();
    unsigned int getValueFromArray(int index);
    double sumOfArray();
    void PrintArray();
};

#endif /* VECTOR_H_ */

Кто-нибудь знает, почему это не работает? Спасибо

1 Ответ

0 голосов
/ 14 апреля 2019

В вашем Vector отсутствует правильный конструктор копирования.

Vector temp = *xp;
//NOT EQUAL TO:
//Vector temp;
//temp=*xp;

Вышеприведенный оператор не будет вызывать operator=(const Vector &), даже если есть знак равенства.Следующая строка является правильной и эквивалентной:

Vector temp(*xp);

Причина в том, что это копия Инициализация - temp создана, и поэтому должен быть вызван конструктор - в частности, копияконструктор Vector(const Vector &).Который вы явно не объявили и поэтому был использован по умолчанию.

Затем создается неглубокая копия, temp и *xp затем совместно используют один и тот же массив, и когда оба их деструктора будут вызваны, второй попытается удалить уже удаленную память - неопределенное поведение, которое вызывает отладчик Visual Studio(по крайней мере, в режиме отладки).

Решение состоит в том, чтобы сделать правильную глубокую копию - создать новый массив и скопировать его содержимое:

#include <algorithm> #Contains std::copy_n
Vector::Vector(const Vector& other)
{
    name=other.name;
    size=other.size;
    //Creates a new array
    array= new unsigned int[size];
    //Copies the array contents
    std::copy_n(other.array,size,array);
    Boo=other.Bool;
}

Также это яркий пример того, почемуне использовать сырую память.Я понял, что вы реализуете пользовательский вектор и не хотите использовать std::vector для array, но по крайней мере используйте std::unique_ptr.Если бы вы только что сделали это, вам бы не пришлось задавать этот вопрос в первую очередь, так как компилятор жаловался бы, а отладчику не пришлось бы выполнять работу компилятора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...