我试图实现一个行主要数组,它基本上是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;
}
我最终得到了分段错误。我做错了什么。
答案 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( )
而不是[ ]
,以便为越界访问引发异常,而不是导致未定义的行为。