Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.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++_Memory Management_Memory Leaks - Fatal编程技术网

C++ 模板化动态阵列上的内存泄漏

C++ 模板化动态阵列上的内存泄漏,c++,memory-management,memory-leaks,C++,Memory Management,Memory Leaks,我有一个家庭作业,要求我有一个狗的仓库。我必须有一个动态数组,模板化。由于某些原因,我得到了很多内存泄漏,我不知道它们是从哪里来的。我尝试过使用Deleaker,但它在源文件中显示“未知” 老实说,我不知道应该在哪里释放内存,因为我不能使用delete 这是我的动态数组定义和声明(不是全部,直到析构函数),如果有帮助的话 template <typename T> class DynamicVector { private: T* elems; int size;

我有一个家庭作业,要求我有一个狗的仓库。我必须有一个动态数组,模板化。由于某些原因,我得到了很多内存泄漏,我不知道它们是从哪里来的。我尝试过使用Deleaker,但它在源文件中显示“未知”

老实说,我不知道应该在哪里释放内存,因为我不能使用
delete

这是我的动态数组定义和声明(不是全部,直到析构函数),如果有帮助的话

template <typename T>
class DynamicVector
{
private:
    T* elems;
    int size;
    int capacity;

public:
    // default constructor for a DynamicVector
    DynamicVector(int capacity = 10);

    // copy constructor for a DynamicVector
    DynamicVector(const DynamicVector& v);
    ~DynamicVector();
    DynamicVector& operator=(const DynamicVector& v);
};
template <typename T>
DynamicVector<T>::DynamicVector(int capacity)
{
    this->size = 0;
    this->capacity = capacity;
    this->elems = new T[capacity];
}

template <typename T>
T& DynamicVector<T>::operator[](int index)
{
    return this->elems[index];
}

template <typename T>
DynamicVector<T>::DynamicVector(const DynamicVector<T>& v)
{
    this->size = v.size;
    this->capacity = v.capacity;
    this->elems = new T[this->capacity];
    for (int i = 0; i < this->size; i++)
        this->elems[i] = v.elems[i];
}

template <typename T>
DynamicVector<T>::~DynamicVector()
{
    delete[] this->elems;
}

template <typename T>
DynamicVector<T>& DynamicVector<T>::operator=(const DynamicVector<T>& v)
{
    if (this == &v)
        return *this;

    this->size = v.size;
    this->capacity = v.capacity;

    auto aux = new T[this->capacity];

    delete[] this->elems;

    this->elems = aux;
    for (int i = 0; i < this->size; i++)
        this->elems[i] = v.elems[i];

    return *this;
}

正如您所注意到的,我在这些类中只有构造函数,所以考虑到三的规则,可能这就是问题所在

为什么不直接使用
std::vector

动态分配确实很棘手;您必须遵循RAII的推荐但未记录的模式,并满足以下几个要求:复制/移动构造函数、赋值运算符、交换函数、析构函数。你最好坚持使用std::vector,除非-当然-它被禁止。

所以要花很长的时间定义所有的特殊函数-以及在其中一些函数中使用的交换函数,以便重构代码。如果这些函数中的任何一个被保留为默认值,那么迟早会有指针悬空、重复删除、使用已删除的指针,并有希望提前崩溃以完成噩梦。 必须正确定义所有特殊成员。
“big5”(以前的“big3”)是实现RAII的惯用方法。您必须定义析构函数复制构造函数和复制赋值(加上移动对应项)。我希望您至少可以使用unique\u ptr。

请提供更多信息。这个例子在我看来是正确的。你有一个复制赋值操作符吗?我觉得很好。唯一不同的是,在更改副本分配中向量的大小和容量之前,我会调用
new
,这样在出现异常时不会得到无效的对象。@JHBonarius是的,这是一个HW分配,我还不允许使用std::vector:(@BryukiHK,类似于“我们正在教你骑自行车,但你还不能使用踏板。”;)这不是答案,而是一条评论。你的问题实际上已经在评论中得到了回答:因为这是一项家庭作业,所以被禁止使用。(可能是为了重现std::vector)
class Dog
{
private:
    std::string breed;
    std::string name;
    int age;
    std::string photograph;

public:
    // default constructor for a dog
    Dog();

    // constructor with parameters
    Dog(const std::string& breed, const std::string& name, const int& age, const std::string& photograph);
    // returns true if two dogs have the same name
    bool operator==(const Dog & d);
    //returns the breed
    std::string getBreed() const { return breed; }
    //returns the name
    std::string getName() const { return name; }
    //returns the age
    int getAge() const { return age; }
    //returns the photograph
    std::string getPhotograph() const { return photograph; }
    void setName(const std::string& n);
    void setAge(const int& a);
    void show();
};

class Repository
{
private:
    DynamicVector<Dog> dogs;
    int current;

public:
    /*
    Default constructor.
    Initializes an object of type repository.
    */
    Repository();

    /*
    Adds a dog to the repository.
    Input: d - Dog.
    Output: the dog is added to the repository.
    */
    void addDog(const Dog& d);

    //I have more methods here but they are irrelevant
}