将动态数组作为副本传递给递归函数 C++

passing an dynamic array as copy to recursive function c++

本文关键字:递归函数 C++ 副本 动态 数组      更新时间:2023-10-16

我正在为旅行推销员类型的问题编写回溯方法的代码。因此,在每个点上,我将递归其余未访问的点。

我无法使用除 cout、cin、new 和 delete 以外的任何库/函数(所以没有矢量)。因此,对于这个问题,我想跟踪到目前为止我访问过的所有点。我为此使用动态布尔数组。所以我想将动态数组作为值传递给函数以跟踪这一点。

这是我迄今为止尝试过的。我试图将数组包装在结构中,但内存取消分配(删除)出现错误(分段错误)

typedef struct Barray{
    bool* a;
    int size;
    Barray(int size) { a = new bool[size]; this->size = size; }
    Barray(const Barray& in) { 
        if(a) delete[] a; // error
        a = new bool[in.size];
        this->size = in.size;
        for (int i = 0; i < in.size; i++)
            a[i] = in.a[i];
    }
    ~Barray() { delete[] a; } // error
}barray;

这是我的递归函数调用

void find_mindist(barray visited, int dist_now, int cur_p) {
    if (base condition)
    {return ;} 
    for (int i = 0; i < n; i++) {
        if (visited.a[i]) continue;
        barray tdist = visited;
        tdist.a[i] = true;
        int ndist = dist_now + dist(points[cur_p], points[i]);
        find_mindist(tdist, ndist, i);
    }
    return ;
}

所以我的问题是——

  • 如何将动态数组作为值传递给函数?
  • 为什么上面的delete给出错误?

首先,对于本地访问的信息,推荐的方法不是无休止地复制整个访问的馆藏,而是mark->recurse->unmark的方法。因此,无论您做什么,请为访问的信息保留一个布尔数组,并根据您的需要更新其内容。

出现其他问题是因为您尝试删除复制构造函数中未初始化的指针。此外,赋值运算符也应重载,以避免不愉快的意外。但是,如果您不再复制访问过的信息,这些都无关紧要。

问题是这是一个复制构造函数。 因此,在输入时,a是未初始化的(因此包含垃圾),因此delete无效。

    Barray(const Barray& in) { 
        if(a) delete[] a; // error
        a = new bool[in.size];
        this->size = in.size;
        for (int i = 0; i < in.size; i++)
            a[i] = in.a[i];
    }

只需删除delete行即可。 此外,更喜欢初始化成员,而不是而不是分配它们,因此:

    Barray(const Barray& in) 
    : a(new bool[in.size])
    , size(in.size) { 
        for (int i = 0; i < in.size; i++)
            a[i] = in.a[i];
    }

另外,请记住三法则。 您需要一个复制赋值运算符。 最简单的是:

Barry& operator=(const Barray& in) = delete;

如果您尝试使用它,这只会强制出现编译错误! 更好的是:

Barry& operator=(const Barray in) { // **NOTE** pass by value!
   std::swap(this.a, in.a);
   std::swap(this.size, in.size);
}

此版本提供了强大的异常保证。 您不得使用std::swap,因此您必须自己编写,或者手写(您可以选择)。

最后,如果你发现自己返回了一个 Barray,你应该编写一个移动构造函数:

    Barray(Barray &&in)
    : a(in.a)
    , size(in.size) {
        in.a = nullptr;
    }

这样可以节省大量复制!