首页 > 解决方案 > 如何修复“free(): double free detected in tcache 2”错误?

问题描述

因此,我创建了一个名为 unorderedSet 的派生类模板,它使用指针成员变量来保存堆上数组的位置(使用 new)。

我试图重载算术运算符以找到两个不同 unorderedSet 对象的交集和并集,而我迄今为止编写的代码(在本网站上的另一个用户的帮助下)管理它。但是,在运行程序时,我得到标题中的错误。我将在下面发布我的代码的相关部分。

template <class elemType>
class unorderedSet: public unorderedArrayListType<elemType>
{
public:
  void insertAt(int location, const elemType& insertItem);
  void insertEnd(const elemType& insertItem);
  void replaceAt(int location, const elemType& repItem);
  const unorderedSet<elemType> operator+(const unorderedSet<elemType>&);
  // Function to overload the binary operator + to find the union of a pair/group of sets
  // Postcondition: Finds the union of the sets

  const unorderedSet<elemType> operator-(const unorderedSet<elemType>&);
  // Function to overload the binary operator - to find the intersection of a pair/group of sets
  // Postcondition: Finds the intersection of the sets
  
  unorderedSet(int size = 100);
  unorderedSet(const unorderedSet<elemType>& otherSet);
  ~unorderedSet();
  
protected:
  elemType *set;
  int length;
  int maxSize;
};

template <class elemType>
const unorderedSet<elemType> unorderedSet<elemType>::operator+(const unorderedSet<elemType>& otherSet)
{
  unorderedSet<elemType> unSet(this->length + otherSet.length); // Initializes new set to hold values of the union set

  for (int i = 0; i < this->length; i++)
    unSet.insertEnd(this->list[i]); // Assigns all values of the activating operand to the union set using insertEnd
  
  for (int i = 0; i < otherSet.length; i++)
    unSet.insertEnd(otherSet.list[i]); // Calls insertEnd() to both check for duplicate values and add unique values to the union of the sets

  return unSet; // Should return the union set, but dumps the core at the moment
} // end operator overload

template <class elemType>
unorderedSet<elemType>::unorderedSet(int size) : unorderedArrayListType<elemType>(size)
{
  if (size <= 0)
  {
    cout << "The array size must be positive. Creating an array of the size 100. " << endl;

    this->maxSize = 100;
  }
  else
    this->maxSize = size;

    this->length = 0;

    set = new elemType[this->maxSize];
}

template <class elemType>
unorderedSet<elemType>::~unorderedSet()
{
  delete [] set;
}

template <class elemType>
unorderedSet<elemType>::unorderedSet(const unorderedSet<elemType>& otherSet)
{
  this->maxSize = otherSet.maxSize;
  this->length = otherSet.length;

  set = new elemType[this->maxSize];

  for (int j = 0; j < length; j++)
    set[j] = otherSet.set[j];
}

以下代码来自我的测试客户端程序。

int main() 
{
  int intArr1[6] = {0, 1, 2, 3, 4, 5};
  unorderedSet<int> testIntSet1;

  for (int i = 0; i < (sizeof(intArr1) / sizeof(intArr1[0])); i++)
    testIntSet1.insertEnd(intArr1[i]);
  // Some more code before the function call
  
  int intArr2[6] = {0, 1, 3, 6, 7, 9};
  unorderedSet<int> testIntSet2, testIntSet3;

  for (int i = 0; i < (sizeof(intArr2) / sizeof(intArr2[0])); i++)
    testIntSet2.insertEnd(intArr2[i]);

  testIntSet3 = testIntSet1 + testIntSet2;
  // Some more code
}

我在这个类的基类的基类中还有一个赋值运算符重载函数。代码如下

template <class elemType>
const arrayListType<elemType>& arrayListType<elemType>::operator= (const arrayListType<elemType>& otherList)
{
  if (this != &otherList)    //avoid self-assignment
  {
    delete [] list;
    this->maxSize = otherList.maxSize;
    this->length = otherList.length;
 
    list = new elemType[this->maxSize];

    for (int i = 0; i < this->length; i++)
      list[i] = otherList.list[i];
  }

  return *this;
}

我试图在我的 unorderedSet 类中创建另一个版本,但是当我运行它时,testIntSet3 变量什么也不输出(甚至没有一些随机垃圾)。我决定删除它,因为代码之前似乎至少可以正常运行。

标签: c++

解决方案


一个问题是您orderedSet缺少用户定义的赋值运算符:

template <class elemType>
class unorderedSet: public unorderedArrayListType<elemType>
{
  public:
      unorderedSet<elemType>& operator=(const unorderedSet<elemType>&);
  //...
};

该功能需要实现。最简单的方法是,假设您有一个功能齐全、工作正常的复制构造函数和析构函数 for unorderedSet,如下所示:

template <class elemType>
unorderedSet<elemType>& unorderedSet<elemType>::operator=(const unorderedSet<elemType>& otherSet)
{
   if (this != &otherSet)
   {
      unorderedSet<elemType> temp = otherSet;
      std::swap(temp.set, set);
      std::swap(temp.length, length);
      std::swap(temp.maxSize, maxSize);
   }
   return *this;
}

这使用了复制交换成语

arrayListType的赋值运算符应该写在同一个fashipn中。


推荐阅读