Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 析构函数使用中的问题_C++_Destructor - Fatal编程技术网

C++ 析构函数使用中的问题

C++ 析构函数使用中的问题,c++,destructor,C++,Destructor,我开始学习c++时遇到了这个问题。如果不使用析构函数,则一切正常,但添加析构函数时,会出现以下错误: *** Error in `./arraylist.o': double free or corruption (fasttop): 0xb71ab360 *** ./test_arraylist.sh: line 2: 513 Aborted ./arraylist.o 我的源代码: #include <iostream> #include "

我开始学习c++时遇到了这个问题。如果不使用析构函数,则一切正常,但添加析构函数时,会出现以下错误:

*** Error in `./arraylist.o': double free or corruption (fasttop): 0xb71ab360 ***
./test_arraylist.sh: line 2:   513 Aborted                 ./arraylist.o
我的源代码:

#include <iostream>
#include "jppsys.h"

namespace jpparl {
    template <class T> class ArrayList {
        private:
            T *array;
            int step;
            long totalSize;
            long usedSize = 0;
        public:
            ArrayList(long step) {
                this->step = step;
                totalSize = step;
                array = new T[step];
                std::cout << "\nCreate " << array << "\n";
            }

            ArrayList() {
                this->step = 8;
                totalSize = step;
                array = new T[step];
                std::cout << "\nCreate " << array << "\n";
            }

            ArrayList(const ArrayList &arraylist) {
                step = arraylist.step;
                totalSize = arraylist.totalSize;
                usedSize = arraylist.usedSize;
                array = new T[totalSize];
                std::copy(arraylist.array, arraylist.array + totalSize, array);
                std::cout << "\nCopy " << array << "\n";
            }

            ~ArrayList() {
                std::cout << "\nDelete " << array << "\n";
                // delete[] array;
                // ^^^^^^^^^^^^^^^ error here
            }

            void add(T elem, long index) {
                if (usedSize == totalSize) totalSize += step;

                T *tmp = new T[totalSize];
                std::copy(array, array + index, tmp);
                std::copy(array + index, array + index + usedSize, tmp + index + 1);
                delete[] array;
                tmp[index] = elem;
                array = tmp;

                usedSize++;
            }

            void remove(long index) {
                if (usedSize == totalSize - step) totalSize -= step;
                T *tmp = new T[totalSize];
                std::copy(array, array + index, tmp);
                std::copy(array + index + 1, array + usedSize, tmp + index);
                delete[] array;
                array = tmp;

                usedSize--;
            }

            T get(long index) {
                return array[index];
            }

            long size() {
                return usedSize;
            }

            long getTotalSize() {
                return totalSize;
            }
    };

}

using namespace jpparl;
using namespace std;
int main() {
    ArrayList<ArrayList<int>> al(1);
    ArrayList<int> al2(1);
    cout << "\nAdding 256\n";
    al2.add(256,0); // al2.get(0) - 256
    cout << "\nAdding al2\n";
    al.add(al2, 0); // adds copy of a2, al.get(0) - copy of.a2
    cout << "\nRemoving 256\n";
    al2.remove(0); // removes 256 from al2, not from a1
    cout << al2.get(0) << " - must be 0      " << al.get(0).get(0) << "     - must be 256\n";
    cout << al2.size() << " - must be 0     " << al.get(0).size() << "     - must be 1\n";
}
使用析构函数:

Create 0xb86d4f30

Create 0xb86d4f18

Create 0xb86d5360

Adding 256

Adding al2

Copy 0xb86d5360

Create 0xb86d53a0

Delete 0xb86d4f30

Delete 0xb86d5360

Removing 256
0 - must be 0
Copy 0xb86d5370
256     - must be 256

Delete 0xb86d5370
0 - must be 0
Copy 0xb86d53d8
1      - must be 1

Delete 0xb86d53d8

Delete 0xb86d53c8

Delete 0xb86d5388
Create 0xb71aaf30

Create 0xb71aaf18

Create 0xb71ab360

Adding 256

Adding al2

Copy 0xb71ab360

Create 0xb71ab3a0

Delete 0xb71aaf30

Delete 0xb71ab360

Removing 256
0 - must be 0
Copy 0xb71ab370
0     - must be 256

Delete 0xb71ab370
0 - must be 0
Copy 0xb71ab370
1     - must be 1

Delete 0xb71ab370

Delete 0xb71ab360

Delete 0xb71ab388

Delete 0xb71ab360
*** Error in `./arraylist.o': double free or corruption (fasttop): 0xb71ab360 ***
./test_arraylist.sh: line 2:   513 Aborted                 ./arraylist.o
我将非常感谢您的帮助

如前所述,我需要添加一个作业操作员

#include <iostream>

namespace jpparl {
    template <class T> class ArrayList {
        private:
            T *array;
            int step;
            long totalSize;
            long usedSize = 0;

            void copy(const ArrayList &arraylist) {
                step = arraylist.step;
                totalSize = arraylist.totalSize;
                usedSize = arraylist.usedSize;
                array = new T[totalSize];
                std::copy(arraylist.array, arraylist.array + totalSize, array);
                std::cout << "\nCopy " << array << "\n";
            }

        public:
            ArrayList(long step) {
                this->step = step;
                totalSize = step;
                array = new T[step];
                std::cout << "\nCreate " << array << "\n";
            }

            ArrayList() {
                this->step = 8;
                totalSize = step;
                array = new T[step];
                std::cout << "\nCreate " << array << "\n";
            }

            ArrayList(const ArrayList &arraylist) {
                copy(arraylist);
            }

            ~ArrayList() {
                std::cout << "\nDelete " << array << "\n";
                delete[] array;
            }

            ArrayList& operator = (const ArrayList &arraylist) {
                copy(arraylist);
            }

            void add(T elem, long index) {
                if (usedSize == totalSize) totalSize += step;

                T *tmp = new T[totalSize];
                std::copy(array, array + index, tmp);
                std::copy(array + index, array + index + usedSize, tmp + index + 1);
                delete[] array;
                tmp[index] = elem;
                array = tmp;

                usedSize++;
            }

            void remove(long index) {
                if (usedSize == totalSize - step) totalSize -= step;
                T *tmp = new T[totalSize];
                std::copy(array, array + index, tmp);
                std::copy(array + index + 1, array + usedSize, tmp + index);
                delete[] array;
                array = tmp;

                usedSize--;
            }

            T get(long index) {
                return array[index];
            }

            long size() {
                return usedSize;
            }

            long getTotalSize() {
                return totalSize;
            }
    };

}

using namespace jpparl;
using namespace std;
int main() {
    ArrayList<ArrayList<int>> al(1);
    ArrayList<int> al2(1);
    cout << "\nAdding 256\n";
    al2.add(256,0); // al2.get(0) - 256
    cout << "\nAdding al2\n";
    al.add(al2, 0); // adds copy of a2, al.get(0) - copy of.a2
    cout << "\nRemoving 256\n";
    al2.remove(0); // removes 256 from al2, not from a1
    cout << al2.get(0) << " - must be 0      " << al.get(0).get(0) << "     - must be 256\n";
    cout << al2.size() << " - must be 0     " << al.get(0).size() << "     - must be 1\n";
}
#包括
名称空间jpparl{
模板类ArrayList{
私人:
T*阵列;
整数步;
总尺寸长;
长时间使用的大小=0;
无效副本(常量数组列表和数组列表){
step=arraylist.step;
totalSize=arraylist.totalSize;
usedSize=arraylist.usedSize;
数组=新的T[totalSize];
std::copy(arraylist.array,arraylist.array+totalSize,array);
正如前面所说,我需要添加一个赋值操作符

#include <iostream>

namespace jpparl {
    template <class T> class ArrayList {
        private:
            T *array;
            int step;
            long totalSize;
            long usedSize = 0;

            void copy(const ArrayList &arraylist) {
                step = arraylist.step;
                totalSize = arraylist.totalSize;
                usedSize = arraylist.usedSize;
                array = new T[totalSize];
                std::copy(arraylist.array, arraylist.array + totalSize, array);
                std::cout << "\nCopy " << array << "\n";
            }

        public:
            ArrayList(long step) {
                this->step = step;
                totalSize = step;
                array = new T[step];
                std::cout << "\nCreate " << array << "\n";
            }

            ArrayList() {
                this->step = 8;
                totalSize = step;
                array = new T[step];
                std::cout << "\nCreate " << array << "\n";
            }

            ArrayList(const ArrayList &arraylist) {
                copy(arraylist);
            }

            ~ArrayList() {
                std::cout << "\nDelete " << array << "\n";
                delete[] array;
            }

            ArrayList& operator = (const ArrayList &arraylist) {
                copy(arraylist);
            }

            void add(T elem, long index) {
                if (usedSize == totalSize) totalSize += step;

                T *tmp = new T[totalSize];
                std::copy(array, array + index, tmp);
                std::copy(array + index, array + index + usedSize, tmp + index + 1);
                delete[] array;
                tmp[index] = elem;
                array = tmp;

                usedSize++;
            }

            void remove(long index) {
                if (usedSize == totalSize - step) totalSize -= step;
                T *tmp = new T[totalSize];
                std::copy(array, array + index, tmp);
                std::copy(array + index + 1, array + usedSize, tmp + index);
                delete[] array;
                array = tmp;

                usedSize--;
            }

            T get(long index) {
                return array[index];
            }

            long size() {
                return usedSize;
            }

            long getTotalSize() {
                return totalSize;
            }
    };

}

using namespace jpparl;
using namespace std;
int main() {
    ArrayList<ArrayList<int>> al(1);
    ArrayList<int> al2(1);
    cout << "\nAdding 256\n";
    al2.add(256,0); // al2.get(0) - 256
    cout << "\nAdding al2\n";
    al.add(al2, 0); // adds copy of a2, al.get(0) - copy of.a2
    cout << "\nRemoving 256\n";
    al2.remove(0); // removes 256 from al2, not from a1
    cout << al2.get(0) << " - must be 0      " << al.get(0).get(0) << "     - must be 256\n";
    cout << al2.size() << " - must be 0     " << al.get(0).size() << "     - must be 1\n";
}
#包括
名称空间jpparl{
模板类ArrayList{
私人:
T*阵列;
整数步;
总尺寸长;
长时间使用的大小=0;
无效副本(常量数组列表和数组列表){
step=arraylist.step;
totalSize=arraylist.totalSize;
usedSize=arraylist.usedSize;
数组=新的T[totalSize];
std::copy(arraylist.array,arraylist.array+totalSize,array);

std::cout行中缺少asignment运算符

al.add(al2, 0);

al2是浅层复制的,这意味着两个对象共享同一个缓冲区。然后,它被删除两次。一次是在传递给add方法的临时数据被销毁之后,一次是在主函数的末尾。

缺少asignment操作符。在

al.add(al2, 0);

al2是浅层复制的,这意味着两个对象共享同一个缓冲区。然后它会被删除两次。一次是在传递给add方法的临时数据被销毁之后,一次是在主函数的末尾。

您的类不遵循,这基本上说明,如果类需要实现复制构造函数,则复制assig它可能需要实现所有这三个操作符(C++11通过添加移动构造函数和移动赋值操作符引入移动语义,从而形成规则5)

您的类有一个复制构造函数和一个析构函数,但它缺少一个复制赋值运算符,当复制本身就是类实例的元素时,
std::copy()
会调用该运算符。您的类也缺少一个移动构造函数和移动赋值运算符,因为您使用的是C++11(通过虚拟的方式初始化
usedSize
成员)

此外,您的
add()
remove()
方法也没有正确管理数组。不需要在每次添加/删除操作中重新分配数组。这会破坏
步骤
成员的全部目的。仅在实际需要时重新分配(超出当前
步骤
的增长/收缩)

在这种情况下,最好的选择是简单地使用
std::vector
而不是手动数组,例如:

#include <vector>
#include <utility>
#include "jppsys.h"

namespace jpparl {
    template <class T>
    class ArrayList {
    private:
        std::vector<T> array;

    public:
        void add(const T &elem) {
            array.push_back(elem);
        }

        void add(const T &elem, long index) {
            array.insert(array.begin()+index, std::move(elem));
        }

        void remove(long index) {
            array.erase(array.begin()+index);
        }

        T get(long index) {
            return array[index];
        }

        long size() {
            return array.size();
        }

        long getTotalSize() {
            return array.capacity();
        }
    };
}
#include <algorithm>
#include <utility>
#include "jppsys.h"

namespace jpparl {
    template <class T>
    class ArrayList {
    private:
        T *array;
        int step;
        long totalSize;
        long usedSize = 0;

    public:
        ArrayList(long step = 8) {
            this->step = step;
            totalSize = step;
            array = new T[totalSize];
        }

        ArrayList(const ArrayList &src) {
            step = src.step;
            totalSize = src.totalSize;
            usedSize = src.usedSize;
            array = new T[totalSize];
            std::copy(src.array, src.array + usedSize, array);
        }

        ArrayList(ArrayList &&src) {
            step = src.step;
            totalSize = 0;
            usedSize = 0;
            array = nullptr;
            src.swap(*this);
        }

        ~ArrayList() {
            delete[] array;
        }

        ArrayList& operator=(const ArrayList &rhs) {
            if (&rhs != this)
                ArrayList(rhs).swap(*this);
            return *this;
        }

        ArrayList& operator=(ArrayList &&rhs) {
            rhs.swap(*this);
            return *this;
        }

        void swap(ArrayList &other) {
            std::swap(step, other.step);
            std::swap(totalSize, other.totalSize);
            std::swap(usedSize, other.usedSize);
            std::swap(array, other.array);
        }

        void add(const T &elem, long index = -1) {
            if (index == -1) index = usedSize;
            if (usedSize == totalSize) {
                ArrayList tmp(totalSize + step);
                std::copy(array, array + usedSize, tmp.array);
                std::swap(array, tmp.array);
                totalSize = tmp.totalSize;
            }
            std::copy_backward(array + index, array + index + (usedSize - index), array + usedSize + 1);
            array[index] = elem;
            ++usedSize;
        }

        void remove(long index) {
            std::copy(array + index + 1, array + usedSize, array + index);
            --usedSize;
            if ((usedSize == (totalSize - step)) && (totalSize > step)) {
                ArrayList tmp(totalSize - step);
                std::copy(array, array + usedSize, tmp.array);
                std::swap(array, tmp.array);
                totalSize = tmp.totalSize;
            }
        }

        T get(long index) {
            return array[index];
        }

        long size() {
            return usedSize;
        }

        long getTotalSize() {
            return totalSize;
        }
    };
}
#包括
#包括
#包括“jppsys.h”
名称空间jpparl{
模板
类数组列表{
私人:
std::矢量阵列;
公众:
无效添加(常量T&elem){
数组。推回(elem);
}
无效添加(常量T&elem,长索引){
插入(array.begin()+索引,std::move(elem));
}
无效删除(长索引){
array.erase(array.begin()+索引);
}
T get(长索引){
返回数组[索引];
}
长码(){
返回array.size();
}
长getTotalize(){
返回array.capacity();
}
};
}
如果这不是您的选项,如果您必须使用手动阵列,则在制作阵列副本时应使用,例如:

#include <vector>
#include <utility>
#include "jppsys.h"

namespace jpparl {
    template <class T>
    class ArrayList {
    private:
        std::vector<T> array;

    public:
        void add(const T &elem) {
            array.push_back(elem);
        }

        void add(const T &elem, long index) {
            array.insert(array.begin()+index, std::move(elem));
        }

        void remove(long index) {
            array.erase(array.begin()+index);
        }

        T get(long index) {
            return array[index];
        }

        long size() {
            return array.size();
        }

        long getTotalSize() {
            return array.capacity();
        }
    };
}
#include <algorithm>
#include <utility>
#include "jppsys.h"

namespace jpparl {
    template <class T>
    class ArrayList {
    private:
        T *array;
        int step;
        long totalSize;
        long usedSize = 0;

    public:
        ArrayList(long step = 8) {
            this->step = step;
            totalSize = step;
            array = new T[totalSize];
        }

        ArrayList(const ArrayList &src) {
            step = src.step;
            totalSize = src.totalSize;
            usedSize = src.usedSize;
            array = new T[totalSize];
            std::copy(src.array, src.array + usedSize, array);
        }

        ArrayList(ArrayList &&src) {
            step = src.step;
            totalSize = 0;
            usedSize = 0;
            array = nullptr;
            src.swap(*this);
        }

        ~ArrayList() {
            delete[] array;
        }

        ArrayList& operator=(const ArrayList &rhs) {
            if (&rhs != this)
                ArrayList(rhs).swap(*this);
            return *this;
        }

        ArrayList& operator=(ArrayList &&rhs) {
            rhs.swap(*this);
            return *this;
        }

        void swap(ArrayList &other) {
            std::swap(step, other.step);
            std::swap(totalSize, other.totalSize);
            std::swap(usedSize, other.usedSize);
            std::swap(array, other.array);
        }

        void add(const T &elem, long index = -1) {
            if (index == -1) index = usedSize;
            if (usedSize == totalSize) {
                ArrayList tmp(totalSize + step);
                std::copy(array, array + usedSize, tmp.array);
                std::swap(array, tmp.array);
                totalSize = tmp.totalSize;
            }
            std::copy_backward(array + index, array + index + (usedSize - index), array + usedSize + 1);
            array[index] = elem;
            ++usedSize;
        }

        void remove(long index) {
            std::copy(array + index + 1, array + usedSize, array + index);
            --usedSize;
            if ((usedSize == (totalSize - step)) && (totalSize > step)) {
                ArrayList tmp(totalSize - step);
                std::copy(array, array + usedSize, tmp.array);
                std::swap(array, tmp.array);
                totalSize = tmp.totalSize;
            }
        }

        T get(long index) {
            return array[index];
        }

        long size() {
            return usedSize;
        }

        long getTotalSize() {
            return totalSize;
        }
    };
}
#包括
#包括
#包括“jppsys.h”
名称空间jpparl{
模板
类数组列表{
私人:
T*阵列;
整数步;
总尺寸长;
长时间使用的大小=0;
公众:
ArrayList(长步长=8){
这个->步骤=步骤;
总尺寸=步长;
数组=新的T[totalSize];
}
ArrayList(常量ArrayList和src){
步骤=src.step;
totalSize=src.totalSize;
usedSize=src.usedSize;
数组=新的T[totalSize];
std::copy(src.array,src.array+usedSize,array);
}
ArrayList(ArrayList&&src){
步骤=src.step;
totalSize=0;
usedSize=0;
数组=空ptr;
src.掉期(*本);
}
~ArrayList(){
删除[]数组;
}
ArrayList和运算符=(常量ArrayList和rhs){
如果(&rhs!=此)
ArrayList(rhs).swap(*此项);
归还*这个;
}
ArrayList和运算符=(ArrayList和rhs){
rhs.掉期(*本);
归还*这个;
}
无效交换(ArrayList和其他){
标准::交换(步骤,其他步骤);
std::swap(totalSize,other.totalSize);
std::swap(usedSize,other.usedSize);
std::swap(array,other.array);
}
无效添加(常量T&elem,长索引=-1){
如果(索引==-1)索引=usedSize;
如果(usedSize==totalSize){
ArrayList tmp(总大小+步长);
std::copy(数组,数组+usedSize,tmp.array);
std::swap(数组,tmp.array);
totalSize=tmp.totalSize;
}
std::copy_backward(数组+索引,数组+索引+(usedSize-index),数组+usedSize+1);
数组[索引]=元素;
++使用大小;
}
无效删除(长索引){
std::copy(数组+索引+1,数组+usedSize,数组+索引);