在自身内交换对象

avo*_*iva 3 c++ oop destructor double-free delete-operator

我正试图在自己内部交换一个对象.它工作,但当我添加一个析构函数时,它给了我一个双重自由错误.有办法防止这种情况吗?我正在谈论的方法是void swap(SimpleArray &object).

(对不起,如果你在我的帖子中输入了错误的信息之前看过这个...)

#include "TestType.h"
class SimpleArray {

    private: 
        TestType* pArray;
        //TestType* temp;
    public:
        SimpleArray(TestType *array)
        {
            this->pArray = array;
        }
        ~SimpleArray() { delete[] pArray; }
        SimpleArray() { pArray = 0;}
        SimpleArray(const SimpleArray& arg){ pArray = arg.pArray; }
        ~SimpleArray() { delete[] pArray; }
        TestType * get() const{ return pArray; }
        bool isNonNull() const { return pArray != 0; }
        //TestType* pArray;
        void reset(TestType*& p) {this->pArray = p; }
        void reset() { pArray = 0; }

        void swap(SimpleArray &object) { SimpleArray temp; temp = object; object = *this; *this = temp;}
        TestType * release() { pArray = 0; return pArray; }
        TestType& getReference(int a) { return *pArray; }


};
Run Code Online (Sandbox Code Playgroud)

这工作但是一旦我添加了析构函数,它就会给我一个"双重免费或损坏错误".我该如何解决这个问题?这是主要功能在哪里混乱.

bool testGetReleaseSwap() {
    SimpleArray array1;
    if (array1.get() != 0)
        return false;

    TestType* directArray1 = new TestType[100];
    array1.reset(directArray1);
    if (array1.get() != directArray1)
        return false;

    TestType* directArray2 = new TestType[50];
    SimpleArray array2(directArray2);

    array1.swap(array2);
    if (array1.get() != directArray2 || array2.get() != directArray1)
        return false;

    array2.swap(array1);
    if (array1.get() != directArray1 || array2.get() != directArray2)
        return false;

    array1.swap(array1);
    if (array1.get() != directArray1)
        return false;

    if (array1.release() != directArray1 || array2.release() != directArray2)
        return false;

    if (array1.get() != 0 || array2.get() != 0)
        return false;

    delete[] directArray1;
    delete[] directArray2;

    return true;
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*ler 6

这里琐碎的方法temp.release()在最后调用你的swap方法来防止双重删除.

然而,潜在的问题要深刻得多.在C++中,始终保持谁拥有某些东西的严格语义是至关重要的,例如需要删除的内存区域.

一个常见的模式是分配东西的对象也负责清理而不是其他人.这非常适合SimpleArray,但复制构造函数会破坏它,因为它会增加所有者的数量!

要实现共享数据语义,您必须投入更多工作(引用计数等),或者您必须禁止数组复制并将复制构造函数设置为私有.

swap不复制对象的情况下修复工作的简洁方法是:

 void swap(SimpleArray &object) { 
    TestType* temp = object.pArray;
    object.pArray = this->pArray;
    this->pArray = temp;
 }
Run Code Online (Sandbox Code Playgroud)

(也std::swap(object.pArray, pArray);适用)

因为交换阵列的内存区域与单一所有者模式非常吻合,所以这里出错的只是使用完整的对象副本.

您应该阅读C++中的资源管理和所有权语义.除非你完全知道谁拥有什么,否则你的代码总是容易出错.