【问题标题】:Generic vector class using smart pointers in C++在 C++ 中使用智能指针的通用向量类
【发布时间】:2018-08-05 21:55:44
【问题描述】:

我正在尝试(苦苦挣扎)使用 std::unique_ptr 编写通用向量类。在我的构造函数中,我抛出了这个异常:

Exception thrown: write access violation.
std::unique_ptr<int [0],std::default_delete<int [0]> >::operator[](...) returned nullptr.

这是关联的函数:

template <class T>
Vector<T>::Vector(int n, const T &value) {
    capacity = (n > initial_capacity) ? n : initial_capacity;
    size = n;
    for (int i = 0; i < n; i++) {
        data[i] = value;
    }
}

我在 main.cpp 文件中也遇到了错误:

assert(nullVector.getCapacity() == 100); 

我相信这是因为如果可能的话,我没有在 std::unique_ptr 中设置容量。

这是我的头文件的一部分:

#ifndef Vector_h
#define Vector_h



template <class T>
class Vector {
private:

    static constexpr int initial_capacity = 100;

    // Instance variables
    int capacity = 0;
    int size = 0;
    std::unique_ptr<T[]> data = nullptr;

    void deepCopy(const Vector<T> &source) {
        capacity = source.size + initial_capacity;
        for (int i = 0; i < source.size; i++) {
            data[i] = source.data[i];
        }
        size = source.size;
    }

    void expandCapacity() {
        auto oldData = std::move(data);
        capacity *= 2;
        for (int i = 0; i < size; i++) {
            data[i] = oldData[i];
        }
    }

public:

    // Constructors
    Vector() = default;                                 // empty constructor
    Vector(int n, const T &value);                      // constructor
    Vector(Vector<T> const &vec);                       // copy constructor
    Vector<T>& operator=(Vector<T> const &rhs);         // assignment operator

    // Rule of 5
    Vector(Vector<T> &&move) noexcept;                  // move constructor
    Vector& operator=(Vector<T> &&move) noexcept;       // move assignment operator
    ~Vector();                                          // destructor

    // Overload operators
    T& operator[](int index);
    T const& operator[](int index) const;
    bool operator==(const Vector<T>&) const;

    //Vector<T>& operator+=(const Vector<T> &other) {
    //  Vector<T> newValue(size + other.size);

    //  std::copy(this->data, this->data + this->size, newValue.data);
    //  std::copy(other.data, other.data + other.size, newValue.data + this->size);

    //  newValue.swap(*this);
    //}

    friend Vector<T>& operator+(Vector<T> &source1, Vector<T> &source2) {
        int n = source1.getSize() + source2.getSize();
        Vector<T> newSource(n,0);
        for (int i = 0; i < source1.size; i++) {
            newSource[i] = source1[i];
        }

        for (int i = 0; i < source2.size; i++) {
            newSource[i + source1.getSize()] = source2[i];
        }

        return newSource;
    }

    friend std::ostream& operator<<(std::ostream &str, Vector<T> &data) {
        data.display(str);
        return str;
    }

    // Member functions
    void swap(Vector<T> &other) noexcept;
    void display(std::ostream &str) const;
    int getSize() const { return size; }
    int getCapacity() const { return capacity; }
    bool empty() const { return size == 0; }
    void clear() { size = 0; }
    T get(int index) const;
    void set(int index, const T &value);
    void set(int index, T &&value);
    void insert(int index, const T &value); 
    void insert(int index, T &&value);
    void remove(int index);
    void push_back(const T &value);
    void pop_back();

};



template <class T>
Vector<T>::Vector(int n, const T &value) {
    capacity = (n > initial_capacity) ? n : initial_capacity;
    size = n;
    for (int i = 0; i < n; i++) {
        data[i] = value;
    }
}

这是 main.cpp 文件的一部分:

#include <algorithm>
#include <initializer_list>
#include <iostream>
#include <cassert>
#include <ostream>
#include "Vector.h"


int main() {

    ///////////////////////////////////////////////////////////////////////
    ///////////////////////////// VECTOR //////////////////////////////////
    ///////////////////////////////////////////////////////////////////////
    Vector<int> nullVector;                        // Declare an empty Vector
    assert(nullVector.getSize() == 0);                 // Make sure its size is 0
    assert(nullVector.empty());                    // Make sure the vector is empty
    assert(nullVector.getCapacity() == 100);          // Make sure its capacity is greater than 0


}

【问题讨论】:

  • 你没有调用那个构造函数,你调用的是空构造函数(至少在你发布的代码中)。
  • 请不要发布被注释掉的代码——这会让你很难知道你到底在问什么。
  • 请为您的代码创建一个极简版本,以便于调试。取出所有不必要的部分。

标签: c++ vector


【解决方案1】:

没有unique_ptr 的“容量”之类的东西。 std::unique_ptr 所做的只是保持动态分配的对象。它不会自己分配对象。使用std::make_unique()new 创建一个新对象并分配给您的unique_ptr 以保留。

我没有看到您在代码中的任何位置分配任何内存。除非您确实在一段未显示的代码中为您的向量分配内存,否则您的 data 只会指向 nullptr 并试图取消引用它会崩溃(或更糟)。至少你的expandCapacity() 方法似乎没有分配任何内存……

您可能应该看一些材料来了解unique_ptr 和一般的智能指针。例如:How to declare std::unique_ptr and what is the use of it?this

【讨论】:

  • void expandCapacity() { auto oldData = std::move(data);容量 *= 2;数据 = std::make_unique(容量); for (int i = 0; i
  • 我试过你的建议,但还是不行
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-03
  • 1970-01-01
  • 2021-09-20
  • 1970-01-01
  • 2021-12-26
  • 2020-12-04
相关资源
最近更新 更多