C++ 重载赋值运算符函数和复制构造函数中出错

C++ 重载赋值运算符函数和复制构造函数中出错,c++,C++,我目前正在编写一个程序,创建一个动态分配的循环数组。为此,我创建了一个复制构造函数和赋值运算符 当我第二次尝试调用赋值运算符时,出现了一个名为“munmap_chunk():无效指针”的错误。如果我调用它一次,则不会显示错误。我是否正确编写了复制构造函数和赋值运算符?如果需要任何信息,我很乐意提供,谢谢 CircularDynamicArray(const CircularDynamicArray& source){ cout << "copy constructor

我目前正在编写一个程序,创建一个动态分配的循环数组。为此,我创建了一个复制构造函数和赋值运算符

当我第二次尝试调用赋值运算符时,出现了一个名为“munmap_chunk():无效指针”的错误。如果我调用它一次,则不会显示错误。我是否正确编写了复制构造函数和赋值运算符?如果需要任何信息,我很乐意提供,谢谢

CircularDynamicArray(const CircularDynamicArray& source){
    cout << "copy constructor called" << endl;
    m_capacity = source.m_capacity;
    m_size = source.m_size;
    m_front = source.m_front;
    m_rear = source.m_rear;
    arr = new elmtype[source.m_capacity];
    for(int i = 0; i < source.m_capacity; i++) {
        arr[i] = source.arr[i];
    }
}
//overloaded assignment operator
CircularDynamicArray &operator = (const CircularDynamicArray& source) {
    cout << "Overloaded Assignment called" << endl; 
    //check for self assignment
    if (this == &source) {
        return *this;
    }
    m_capacity = source.m_capacity;
    m_size = source.m_size;
    m_front = source.m_front;
    m_rear = source.m_rear;    
    delete[]arr;
    for(int i = 0; i < source.m_capacity; i++) {
        arr[i] = source.arr[i];
    }
    return *this;
}
CirculardDynamicArray(常量CirculardDynamicArray和源代码){
库特
我是否正确编写了复制构造函数和赋值运算符

我要说的是,在编写赋值运算符时,您为自己做的工作比必要的多

如果您已经编写了一个复制构造函数(您已经编写了)和一个析构函数(您没有显示,但我们假设您已经显示了),并且这两个函数都没有bug,那么赋值运算符可以通过使用来实现

通常,在编写赋值运算符之前,您应该努力编写复制构造函数和析构函数,以便使用编写赋值运算符的“技巧”。以下是一个示例:

#include <algorithm>
//...
CircularDynamicArray &operator=(const CircularDynamicArray& source) 
{
  if (this != &source) 
  {
      CircularDynamicArray temp(source);    // Create a copy of what we want
      // get the temp's innards, and give temp our stuff
      std::swap(temp.m_capacity, m_capacity);
      std::swap(temp.m_size, m_size);
      std::swap(temp.m_front, m_front);
      std::swap(temp.m_rear, m_rear);
      std::swap(temp.arr, arr);
  }  // goodbye temp

  return *this; 
}
#包括
//...
CircularDynamicArray和运算符=(常量CircularDynamicArray和源)
{
if(此!=&source)
{
CircularDynamicArray temp(源);//创建所需内容的副本
//拿着临时工的内脏,把我们的东西给临时工
标准:交换(临时m_容量,m_容量);
标准:交换(临时m_尺寸,m_尺寸);
标准:交换(临时m_前端,m_前端);
标准::交换(温度m_后,m_后);
标准::交换(临时arr、arr);
}//再见
归还*这个;
}
无需分配内存,无需
delete[]
调用,您甚至不需要检查自分配(但出于效率目的,无论如何都要检查)。上述操作也是异常安全的。分配操作符工作所需的一切基本上都是完美的

请注意,您需要交换所有成员变量,不要忘记任何一个,因为这将导致无法正常工作

所要做的就是创建传入对象的副本,并用副本交换当前对象的内部。然后副本随旧信息一起消失。这就是为什么需要一个工作副本构造函数(用于
源代码的初始复制)和一个工作析构函数的原因(以便销毁
temp
工作)

我是否正确编写了复制构造函数和赋值运算符

我要说的是,在编写赋值运算符时,您为自己做的工作比必要的多

如果您已经编写了一个复制构造函数(您已经编写了)和一个析构函数(您没有显示,但我们假设您已经显示了),并且这两个函数都没有bug,那么赋值运算符可以通过使用来实现

通常,在编写赋值运算符之前,您应该努力编写复制构造函数和析构函数,以便使用编写赋值运算符的“技巧”。以下是一个示例:

#include <algorithm>
//...
CircularDynamicArray &operator=(const CircularDynamicArray& source) 
{
  if (this != &source) 
  {
      CircularDynamicArray temp(source);    // Create a copy of what we want
      // get the temp's innards, and give temp our stuff
      std::swap(temp.m_capacity, m_capacity);
      std::swap(temp.m_size, m_size);
      std::swap(temp.m_front, m_front);
      std::swap(temp.m_rear, m_rear);
      std::swap(temp.arr, arr);
  }  // goodbye temp

  return *this; 
}
#包括
//...
CircularDynamicArray和运算符=(常量CircularDynamicArray和源)
{
if(此!=&source)
{
CircularDynamicArray temp(源);//创建所需内容的副本
//拿着临时工的内脏,把我们的东西给临时工
标准:交换(临时m_容量,m_容量);
标准:交换(临时m_尺寸,m_尺寸);
标准:交换(临时m_前端,m_前端);
标准::交换(温度m_后,m_后);
标准::交换(临时arr、arr);
}//再见
归还*这个;
}
无需分配内存,无需
delete[]
调用,您甚至不需要检查自分配(但出于效率目的,无论如何都要检查)。上述操作也是异常安全的。分配操作符工作所需的一切基本上都是完美的

请注意,您需要交换所有成员变量,不要忘记任何一个,因为这将导致无法正常工作


所要做的就是创建传入对象的副本,并用副本交换当前对象的内部。然后副本随旧信息一起消失。这就是为什么需要一个工作副本构造函数(用于
源代码的初始复制)和一个工作析构函数的原因(这样,
temp
的销毁就可以工作了)。

您正在
delete[]
ing
arr
,然后立即在下面的循环中使用
arr[i]
对其进行索引。这会导致未定义的行为。如果您已经编写了析构函数,那么如果使用“复制/交换”,您的赋值运算符就不必那么复杂了。事实上,这将是微不足道的--只有5行
std::swap
行--不分配内存,不删除内存,一切都会工作。您正在
delete[]
ing
arr
然后立即使用
arr[i]索引到它中
在下面的循环中。这会导致未定义的行为。如果您编写了析构函数,那么如果您使用“复制/交换”,赋值运算符就不需要那么复杂。事实上,它很简单--只有5行
std::swap
行--不分配内存,不删除内存,所有操作都可以正常工作。