【问题标题】:Program stops - move array to function | C++程序停止 - 将数组移动到函数 | C++
【发布时间】:2019-09-04 06:39:19
【问题描述】:

我有 2 节课。 First Class - 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 类中显示以下代码 sn-p:

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

向量的完整定义:

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

有谁知道为什么它不起作用?谢谢

【问题讨论】:

  • 请提供这些类的完整定义。 Visual Studio 通常会在指针无效时停止并显示一条消息。但是因为array在你提供的sn-ps中没有提到,我不能多说。我的猜测是你的复制构造函数做了浅拷贝,而交换中的temp 变量破坏了xp 的数组。
  • 请在minimal reproducible example 的邮箱中提供Quimby 要求的信息。 (@Quimby,尝试在像你这样的评论中写 [mcve]。)
  • @Yunnosch 感谢您的建议我不知道您不必包含链接并且懒得搜索它。另外我认为直接说明需要什么可能有更好的成功机会:)
  • @Quimby 我已经更新了定义。
  • 我发现违反了Rule of ThreeVector 没有复制构造函数,因此使用隐式定义的构造函数。当一个向量由另一个向量构成时,两者最终都指向同一个array。然后在析构函数中,每个人都试图摧毁它。然后,您的程序会通过双重破坏表现出未定义的行为。

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


【解决方案1】:

您的 Vector 缺少正确的复制构造函数。

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

即使有等号,上述语句也不会调用operator=(const Vector &amp;)。以下行是正确且等效的:

Vector temp(*xp);

原因是这是一个副本初始化 - 创建了temp,因此必须调用构造函数 - 特别是复制构造函数Vector(const Vector &amp;)。您没有明确声明,因此使用了默认值。

然后进行浅拷贝,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。如果您刚刚这样做,您就不必一开始就问这个问题,因为编译器会抱怨,而调试器也不必完成编译器的工作。

【讨论】:

  • @Oz1988 添加了复制构造函数:)
猜你喜欢
  • 2022-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多