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

时间:2017-11-03 07:49:37

标签: c++ arrays recursion

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

我无法使用除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上面会出错?

2 个答案:

答案 0 :(得分:3)

问题是这是一个副本构造函数。因此,在输入时,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];
    }

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

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;
    }

这可以节省大量的复制费用!

答案 1 :(得分:3)

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

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