【问题标题】:C ++ - Problem saving values - values change after savingC ++ - 保存值的问题 - 保存后值发生变化
【发布时间】:2019-04-08 21:17:15
【问题描述】:

我这几天一直在尝试解决内存问题。

我有一个程序,用户可以在其中输入向量及其名称。

程序将所有内容存储在向量类中。

问题是当我打印向量时,值会变为其他值。

我的意思是在Vector::Vector

中名为“array”的数组

有谁知道问题出在哪里?

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_ */

【问题讨论】:

  • 删除此m.~Midgam();。您不需要调用析构函数,它会自动发生,这就是析构函数的全部意义所在。
  • 看起来您发布了一大堆与您的问题无关的代码。请发送minimal reproducible example。另外,why eof() in a loop condition is wrong.
  • 删除这个midgam[i].~Vector();和以前一样。
  • 这段代码中可能有很多错误,但你的错误的直接原因是你没有为你的Vector类定义一个赋值运算符,但是你在这里使用了一个Vector赋值. midgam[iterator]=v;。你应该阅读rule of three。根本问题在于你没有遵循。
  • 当然,如果你避免使用指针,这段代码会变得更容易,使用std::vector而不是指针,你的代码是一半的大小和两倍的可靠性。

标签: c++ c++11 visual-c++ c++14 c++17


【解决方案1】:

正如评论中所说,您错过了在 Vector 上定义 operator=,因此使用默认的 operator= 定义,并且复制一份没有克隆的内容数组

因为当您执行midgam[iterator]=v; 时,您共享v.array,但是当 v 被删除时,那个被删除,然后您在 PrintAll 中访问已删除的数组具有未定义的行为:在您的情况下,不会打印预期值。

你只需要定义operator=,例如Vector(const Vector &amp;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 会产生预期的输出

【讨论】:

  • TNX... 我收到错误:..\Vector.h:20:2: error: extraqualification 'Vector::' on member 'operator=' [-fpermissive] Vector::operator =(const 向量 &v2);
  • @Oz1988 这是因为您将定义直接放在类定义中,而不是放在外面。像声明其他成员一样声明运算符,因此进入类定义Vector &amp; operator=(const Vector &amp;);,并像其他人一样将运算符的定义放在类定义之外
猜你喜欢
  • 1970-01-01
  • 2021-12-23
  • 1970-01-01
  • 1970-01-01
  • 2018-11-23
  • 2023-04-01
  • 2022-08-21
  • 1970-01-01
  • 2018-12-30
相关资源
最近更新 更多