删除未确定大小的数组中的模板指针会导致SIGABRT

时间:2018-04-06 19:32:09

标签: c++ templates pointers memory vector

template <class T>
class Vector {
    int pos = 0;
    int chunkSize;

    T** p = new T*;
public:
    Vector(int chunkSize = 1000) {
        this->chunkSize = chunkSize;
        p[0] = new T[chunkSize];
        std::cout << &p[0] << std::endl;
    }
    ~Vector() {
        for (int i = 0; i < pos / chunkSize; i++) {
            std::cout << &p[i] << std::endl;
            delete [] p[i];
        }
    }

    void pushBack(T val);
    void display();
};

template<class T>
void Vector<T>::pushBack(T val) {
    p[pos / chunkSize][pos % chunkSize] = val;
    if (++pos % chunkSize == 0)
        p[pos / chunkSize] = new T[chunkSize];
}

template<class T>
void Vector<T>::display() {
    for (int i = 0; i < pos; i++)
        std::cout << p[i / chunkSize][i % chunkSize] << " ";
    std::cout << std::endl;
}

我今天正在修补一些代码,并想出了上述内容。我想要做的是创建类似于矢量的东西,使用固定大小的数组,并根据需要创建更多。

我通常使用Java编程,所以内存管理不是我的强项,而且我不确定我所做的事情是完全没问题的。矢量创建得很好,我可以添加任意数量的值。我也可以使用上面的显示功能毫无问题地显示它们。然而,析构函数在尝试删除任何元素时会抛出一个SIGABRT,这就是为什么我在这里,我不知道为什么我可以释放我已经分配并且可以访问的内存,尽管我猜一个可能性是我写作和从内存中读取我不应该访问。这两个cout语句为第0个元素打印相同的地址,我用它来检查我是否一直在查看相同的内存地址。

有人可以向我解释如何正确删除元素,或者为什么我正在做的是一个巨大的错误?

编辑:主类调用此代码如下。

int main() {
    Vector<int> vec;

    for (int i = 0; i < 1000000; i++)
        vec.pushBack(i);
    vec.display();

    return 0;
}

1 个答案:

答案 0 :(得分:0)

问题是您只为一个 T*分配空间并将其存储在p指针中。一旦推回chunksize元素,就会写入p[1],因为它超过为其分配的内存的末尾,导致未定义的行为。其中包括在爆炸前显然工作了一段时间。

每当您需要访问其他元素时,您需要在p数组中分配额外的空间。