如何避免在C ++中析构函数被两次调用?

时间:2019-05-28 06:20:47

标签: c++

我正在测试一个代表我自己为该语言练习而制作的动态数组数据结构的类,但是遇到一个问题,即析构函数被两次调用,从而导致堆损坏错误。

到目前为止,我已经尝试注释掉一些删除词。但是,这会导致不确定的行为。

#include <iostream>
#include "windows.h"
#include <vector>

template<typename T> class Spider {
private:

    T** pointer;

    int maxSize;
    int lengthFilled;
public:
    //default constructor
    Spider()
    {
        pointer = new T * [1];
        maxSize = 1;
        lengthFilled = 0;
    }
    //destructor
    ~Spider()
    {
        for (int i = 0; i < lengthFilled; i++)
        {
            pop();
        }
        delete[] pointer;
    }
    //Pushes an object in
    void push(T thing)
    {
        if (lengthFilled == maxSize)
        {
            increaseSize();
        }

        T* thinggummy = &thing;

        //then save its pointer in the functional array
        pointer[lengthFilled] = thinggummy;
        lengthFilled++;
    }

    //pops the array
    void pop()
    {
        delete pointer[lengthFilled-1];
        setSize(lengthFilled - 1);
        lengthFilled--;
    }
}

int main()
{

    Spider<Spider<int>> test((long long)1);

    for (int i = 0; i < 2; i++)
    {
        test.push(Spider<int>());
        test.get(i).push(2);//this is implemented in the actual code, just omitted here
        std::cout << test.get(i).get(0);
        std::cout << "push complete\n";
    }

    system("pause");

    return 0;
}

该程序的预期结果应为:

2
push complete
2
push complete

按任意键继续...

相反,我在调试日志“检测到严重错误c0000374”中得到了严重错误代码。

1 个答案:

答案 0 :(得分:2)

这里有两个问题:

  1. 就像已经提到的WhiteSword,在执行T *thinggummy = &thing时,您正在使用局部变量的地址。这将造成麻烦,因为一旦离开范围,该地址将无效(除非T解析为引用类型)。
  2. 您对delete数组中的事物调用pointer。但是,这些不是通过new分配的。相反,它们只是某物的地址。因此,您正在尝试释放从未分配的东西。
相关问题