我的程序中哪里有内存泄漏,我该如何解决?

Where is my memory leaking in my program and how would I fix it?

所以我正在为我的 c++ class 做一个作业,我正在尝试使用我的 class 和数组来完成不同的功能。它主要工作直到似乎发生内存泄漏的重载运算符。

#include <iostream>
#include <algorithm>  // for std::copy_n
using namespace std;


class MyArray{
private:
double* a{};
int n{};
public:

MyArray(){
    a = nullptr;
    n = 0;
}   // default constructor
/////////////////////////////////////////////////
explicit MyArray(int size){
    n = size;
    a = new double[size]{};

}  //constructor specifying size
/////////////////////////////////////////////////
MyArray(int size, double def_val) {

    n = size;
    a = new double[size];
    for (int i = 0; i < size; ++i) {
         //def_val=i;
        a[i] = def_val;
    }
} //constructor set to default values and specifying size
/////////////////////////////////////////////////
double  GetA(int i){
    return a[i];
}     //setter
/////////////////////////////////////////////////
int GetN() const{
    return n;
}      //getter
/////////////////////////////////////////////////
void  SetN(int x) {
    n = x;
}     //setter
/////////////////////////////////////////////////
void  SetA(int i, double x) {
    a[i] = x;
}     //getter
/////////////////////////////////////////////////
MyArray(const MyArray & a2, int n) {

    a = new double[n]{};
    n = a2.n;
    for (int i=0; i< n; i++){
        a[i]=a2.a[i];
    }
}     //constructor by copy
/////////////////////////////////////////////////
~MyArray(){
    delete []a;
        } // destructor
/////////////////////////////////////////////////
 MyArray operator=(const MyArray& a2) {

        int new_n = a2.n;
        auto *new_data = new double[new_n];
        std::copy_n(a2.a, new_n, new_data);

        delete[] a;

        n = new_n;
        a = new_data;

        return *this;

}  //assignment
int  get_Size() const{
    return n;
}          //accessor
/////////////////////////////////////////////////
void  push_begin(double first) {
    auto* temp = new double [n+1];
    n++;
    for (int i = 0; i < n-1; i++){
        temp[i+1] = a[i];
    }
    temp[0] = first;
    this-> a = temp;
}
/////////////////////////////////////////////////
void  push_end(double last) {
    a[n] = last;
    n++;
} 
/////////////////////////////////////////////////
void  remove_begin() {
    for (int i = 0; i < n - 1; i++) {
        a[i] = a[i + 1];
    }
    n--;
} //done
/////////////////////////////////////////////////
void  remove_End() {
n--;
} 
/////////////////////////////////////////////////
void  reverse() {
    double temp;
    for(int i=0; i<n/2; i++){
        temp = a[i];
        a[i] = a[n-i-1];
        a[n-i-1] = temp;
    }
} 
/////////////////////////////////////////////////
void  display(){
    for (int i = 0; i < n; i++) {
        cout << a[i] << " ";
    }
    cout << endl;
} 

friend MyArray operator + (MyArray &arr1, MyArray &arr2){
    int n1 = arr1.get_Size();
    int m = arr2.get_Size();
    int size = m + n1;
    MyArray ans(arr2, size);
    for(int i=0; i<size; i++){
        ans.push_end(arr2.a[i]);
    }
    return ans;
} 
};

主要内容:

int main(){
MyArray a(9);
MyArray b(10, 5);
b.push_begin(45);
b.push_end(64);
b.push_end(31);
b.push_begin(908);
b.display();
b.display();
b.display();
b.reverse();
b.display();
MyArray c (a+b);
c.display();         //////The leak seems to happen here but I can't find a memory 
                     /////leak finder that works for me
}

我曾尝试使用 valgrind,但它不想 运行 在我的笔记本电脑上使用。

908 45 8 8 8 8 8 8 64 31
908 45 8 8 8 8 8 8 64 31
908 45 8 8 8 8 8 8 64 31
31 64 8 8 8 8 8 8 45 908
串联数组的最大值为:908
31 64 8 8 8 8 8 8 45 908 6.93003e-310 6.93003e-310 0 0 0

这就是输出结果,我不知道 6.93003e-310 从哪里来,而它绝对应该是 0。

问题是您的 class 没有复制构造函数。 MyArray(const MyArray & a2, int n) 不是 复制构造函数,因为它需要一个额外的参数 n。你实际上并不需要,因为你有 a2.n.

此外,您在 push_begin 中泄漏了 a,并且在 push_end 中完全忘记了调整它的大小(以及在 setN 中,但您似乎没有完全可以使用它)。

最后,您的 operator+ 在几个方面确实存在缺陷。它可以用以下几种方式之一编写:

  1. 创建一个空的新数组,然后从 arr1 创建 push_back 个元素,然后从 arr2.
  2. 创建 push_back 个元素
  3. 创建 arr1 的副本,然后创建 arr2 中的 push_back 个元素。
  4. 创建一个大小为arr1.n + arr2.n的数组,直接填充,不用push_back

代码中的内容是这 3 种方法的奇怪组合。

还有一个文体注释:operator= 应该 return 一个引用(正如评论中指出的那样),并且 operator+ 应该接受常量引用。

不过,这比我在 SO 上看到的大多数家庭作业都要好。