创建行主阵列时出现分段错误

时间:2015-02-17 21:49:36

标签: c++ arrays segmentation-fault

我试图实现一个行主要数组,它基本上是2D数组的单维表示。

这是我的班级定义

class RMA{
    public:

    RMA(){
        size_=0;
        row_=0;
        column_=0;
        arr_ = new double[size_];
    }

    RMA(int n, int m){
        size_ = n*m;
        column_ = m;
        row_ = n;
        if(size_== 0) arr_ = 0;
            else arr_ = new double[size_];
    }

    RMA(const RMA& arr) {
        size_ = arr.size_;
        if(this != &arr){
            delete [] arr_;
            arr_ = new double[size_];
            for(int i=0; i<size_; i++){
                arr_[i] = arr.arr_[i];
            }
        }
        return *this;
    }

    const double& operator() (int n, int m) const{
        return arr_[n*column_+m];
    }

    double& operator()(int n, int m){
        return arr_[n*column_+m];
    }  
    ~RMA(){delete[] arr_ ;}

    private:
        int size_;
        int column_;
        int row_;
        double* arr_;
}

我是一个创建数组的调用函数。

RMA create_array() {
    RMA arr;
    arr = RMA(N, M);
    std::cout<<"success";
    return arr;
}

这是我的客户

int main(int argc, char* argv[]) {

    RMA arr = create_array();
    return 0;
} 

我最终得到了分段错误。我做错了什么。

2 个答案:

答案 0 :(得分:1)

使用操作,而不是克隆数组,取一个对象的浅表副本,当使用析构函数时,它们会尝试释放相同的内存块。

实施以下操作:

RMA::RMA(const RMA&); // copy constructor - clone buffer
RMA& operator=(const &RMA); // assignment - clone buffer, release old

而不是:

 RMA rma;
 rma = RMA(a,b);

使用:

 RMA rma = RMA(a,b) or RMA rma(a,b);

编辑:构造函数代码:

RMA::RMA(const RMA &rma) : size_(0), row_(0), column_(0), buffer_(0)
{
   *this = rma;
}

RMA &operator=(const RMA&rma)
{
   double *old = buffer_;
   size_ = rma.size_;
   row_ = rma.row_;
   column_ = rma.column_;
   buffer_ = new double[size_];
   memcpy(buffer_, rma.buffer_, sizeof(buffer_[0]) * size_);
   delete []old;
   return *this;
}

答案 1 :(得分:0)

最好的解决方案是摆脱所有new / delete,复制构造函数和绒毛。使用私有成员变量来管理内存,然后按照Rule of Zero进行操作。像这样:

struct RMA
{
    RMA(size_t r = 0, size_t c = 0)
        : row(r), column(c), arr(r * c) {}

    const double& operator() (int n, int m) const
        { return arr[n * column + m]; }

    double& operator() (int n, int m)
        { return arr[n * column + m]; }

private:
    std::vector<double> arr;
    size_t row, column;
};

那就是它。你不应该写任何copy-constructor,赋值运算符,移动任何东西,因为默认生成的那些已经做了正确的事情。

NB。 row在我的示例中实际上也是多余的,您可以将其删除并在需要时以arr.size() / column计算。

您可以在向量上使用.at( )而不是[ ],以便为越界访问引发异常,而不是导致未定义的行为。