C ++ - проблема сохранения значений - значения меняются после сохранения - PullRequest
1 голос
/ 09 апреля 2019

Я несколько дней пытался решить проблему с памятью.

У меня есть программа, в которой пользователь вводит вектор и его имя.

Программа сохраняет все вvector class.

Проблема в том, что когда я печатаю вектор, значения меняются на другие значения.

Я имею в виду массив с именем « array » в Vector :: Vector

Кто-нибудь знает, где может быть проблема?

Main.cpp:

# include "Midgam.h"

int main(int argc, char **argv) {
    Midgam m(3,20),m1();
    m.Start();
    m.~Midgam();
    return 0;
}

Midgam.cpp:

#include "Midgam.h"

Midgam::Midgam(int num_of_boxes, int num_of_parties):boxNum(num_of_boxes),maxParties(num_of_parties) {
    iterator = 0;
    midgam = new Vector[maxParties];
}

Midgam::~Midgam() {
    if(midgam)
        for(int i=0; i < iterator; i++)
            midgam[i].~Vector();
    delete [] midgam;
}

void Midgam::Start(){
    int choice;
    while (choice != 6){
        cout << "Please enter your choice" << endl;
        cin >> choice;
        switch (choice) {
        case 1:
            AddParty();
            break;
        case 2:
            cout << "case 2" << endl;
            break;
        case 3:
            cout << "case 3" << endl;
            break;
        case 4:
            cout << "case 4" << endl;
            break;
        case 5:
            cout << "case 5" << endl;
            break;
        case 6:
            break;
        default :
            cerr << "ERROR: invalid command; type 6 for exit" << endl;
        }
    }
    cout << "END OF PROGRAM" << endl;
}

void Midgam::AddParty(){
    string name;
    cout << "Print All:" << endl;
    PrintAll();
    cout << "Insert name:" << endl;
    cin >> name;
    if (name.size() > 12){
        cerr << "Party name is too long, please don't pass the 12 characters!!!" << endl;
        return;
    }
    cout << "Insert values:" << endl;
    Vector v(name,boxNum);
    if (!v.getBool()){
        cerr << "ERROR: invalid input" << endl;
        return;
    }
    int exist = FindPartyByName(name);
    cout << "exist: " << exist << endl;
    if(exist != -1){
        cout << "EXIST" << endl;
        midgam[exist]=v;
        return;
    }
    cout << "iterator: " << iterator <<endl;
    if(iterator >= maxParties){
        cerr << "ERROR: no more new parties" << endl;
        return;
    }
    cout << "iteraator: " << iterator << endl;
    midgam[iterator]=v;
    iterator++;
}

int Midgam::FindPartyByName(string party){
    for (int i=0; i < iterator; i++){
        if (party.compare(midgam[i].getName()) == 0){
            return i;
        }
    }
    return -1;
}

void Midgam::PrintAll(){
    for(int i=0; i < iterator; i++){
        cout << midgam[i].getName() << endl;
        midgam[i].PrintArray();
    }
}

Midgam.h:

#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 AddParty();
    int FindPartyByName(string party);
    void PrintAll();
};

#endif /* MIDGAM_H_ */

Vector.cpp:

#include "Vector.h"

Vector::Vector(string name,int size):name(name),size(size){
    array = new unsigned int[size];
    string results;
    cin.ignore();
    getline(cin,results);
    Bool = StringToArray(results);
}

Vector::Vector(const Vector &v2){
    name=v2.name;
    size=v2.size;
    Bool=v2.Bool;
    array = new unsigned int[size];
    for(int i=0; i < size; i++)
        array[i]=v2.array[i];
}

Vector::Vector(){
    name="";
    size=0;
    array=NULL;
    Bool=true;
}

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

bool Vector::StringToArray(string str){
    stringstream ss(str);
    for(int i=0; i < size ; i++){
        if(ss.eof())
            return false;
        ss >> array[i];
        cout << array[i];
    }
    if(!ss.eof())
        return false;
    return true;
}

bool Vector::getBool(){
    return Bool;
}

string Vector::getName(){
    return name;
}

void Vector::PrintArray(){
    for(int i=0; i < size; i++)
        cout << array[i] << " ";
    cout << endl;
}

Vector.h:

#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(const Vector &v2);
    virtual ~Vector();
    bool StringToArray(string str);
    bool getBool();
    string getName();
    void PrintArray();
};

#endif /* VECTOR_H_ */

1 Ответ

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

Как сказано в комментариях, вы пропустили определение оператора = для Vector , поэтому используется определение по умолчанию operator = , при котором содержимое копируется без клонирование массив .

Из-за этого, когда вы делаете midgam[iterator]=v;, вы делитесь v.array, но этот удаляется при удалении v , и позже вы получаете доступ к удаленному массиву в PrintAll с неопределенное поведение: в вашем случае не выводятся ожидаемые значения.

Вы просто должны определить оператор = , например, сделав как Vector(const Vector &v2):

Vector & Vector::operator=(const Vector &v2) {
  if(array)
    delete [] array;

  // from Vector(const Vector &v2)`
  name=v2.name;
  size=v2.size;
  Bool=v2.Bool;
  array = new unsigned int[size];
  for(int i=0; i < size; i++)
    array[i]=v2.array[i];

  return *this;
}

После этого исполнение:

Please enter your choice
1
Print All:
Insert name:
aze
Insert values:
1 2 3
123exist: -1
iterator: 0
iteraator: 0
Please enter your choice
1
Print All:
aze
1 2 3 
Insert name:
qsd
Insert values:
11 22 33
112233exist: -1
iterator: 1
iteraator: 1
Please enter your choice
1
Print All:
aze
1 2 3 
qsd
11 22 33 
Insert name:
^C

так PrintAll выдает ожидаемые выходные данные

...