首页 > 解决方案 > c++内存分配和重写vector类

问题描述

我正在用 C++ 做一个作业,我们必须重写从抽象 Container 类继承的 std::vector 类。我们必须为“Vector”编写方法,例如 begin()、end()、push_back() 等……这里有许多基本的 std::vector 成员函数:http ://www.cplusplus.com/参考/矢量/矢量/


我的问题是多方面的,主要是因为我是初学者,计算机的记忆力很吸引人。另外,很抱歉,如果这个问题非常具体或在这里有类似的答案,但我真的被困住了,因为这是我第一次处理记忆问题。


这是我的 Container 和 Vector 类实现:

template <typename T> 
class Container {
    protected:
        T* elem;
        int cap;
    public:
        virtual T& operator[](int i) = 0;
        virtual int size() = 0;
        ~ Container() { delete[] elem; }
};

template <typename T>
class Vector: public Container<T> {
    protected:
        using Container<T>::elem;
        using Container<T>::cap;
    private:
        int sz;
    public:
        // constructors
        Vector(); // default constructor
        Vector(int n); // fill constructor #1
        Vector(int n, T fill_val); // fill constructor #2
/*      // ~ Vector(); // destructors
unsure if the above is correct, because of the Container destructor                                
*/  
        // overloaded operators
        T& operator[](int i); // subscript overloading '[]'
        T& operator=(const Vector<T>& V); // assignment overloading '='
        // access methods
        T& front(); //returns a reference to the first element
        T& back(); //returns a reference to the last element
        // iterator methods
        T* begin(); // returns memory address of the first element
        T* end(); // returns memory address at the end
        // size methods
        int size() { return sz; }
        int capacity() { return cap; }
};

第2部分。

何时/为什么需要析构函数?我试图阅读 Stack 上的析构函数,但我感到困惑多于澄清。我假设 SegFault 来自需要释放的内存,并且我知道我应该学习如何使用此分配动态分配内存。构造函数和析构函数对于这个过程至关重要,但有人可以为我尽可能简单地分解它吗?


编辑:

我已经通过实施 Fureeish 的答案修复了分段错误。我的代码已在上面更新。

剩下的唯一查询是析构函数及其用途。我需要实现一个Vector还是会自动调用它Container

标签: c++classinheritancememory-managementsegmentation-fault

解决方案


您决定自己管理内存,但从未分配任何内存。您在new这里和那里缺少一些 s 。例如,给定一个:

Vector(int n, T fill_val) {
    sz = n;
    cap = 2*n;
    for(int i = 0; i < sz; i++) {
        elem[i] = fill_val; 
    }
}

循环for()遍历elem,这是一个未初始化的指针。您将其视为指向动态分配数组的指针,但它只是指向一些垃圾值。请记住 - 首先分配,然后处理(当您决定自己管理内存时。通常您应该更喜欢使用标准实现)。

正确的版本应该是这样的:

Vector(int n, T fill_val) {
    sz = n;
    cap = 2*n;
    elem = new T[cap]; // or cap-1, depending on what you do with `end()`.
    for(int i = 0; i < sz; i++) {
        elem[i] = fill_val; 
    }
}

您在使用其他构造函数时从未遇到过这个问题的事实只是您非常幸运并且未定义的行为是偷偷摸摸的


推荐阅读