【问题标题】:How to initialize vector from array without allocating more storage space?如何在不分配更多存储空间的情况下从数组初始化向量?
【发布时间】:2023-03-06 21:45:01
【问题描述】:

从数组初始化向量的直接方法似乎是:

int sizeArr; int * array = getArray(sizeArr);
std::vector<int> vec(array, array+sizeArr);

在这里,我从一个分配内存空间并通过引用设置sizeArr 的函数获取数组。 {开始编辑} 不幸的是,该函数不是我编写的,我需要处理 C 样式数组,然后以某种方式将其转换为向量。 (如果可能有效)。 {结束编辑}

当我初始化vec 时,显然我正在为它单独分配空间。如果我不打算再使用array 的数据,是否有可能以某种方式将array 指向的数据“移动”到向量vec 并且不为其单独分配任何空间?

【问题讨论】:

  • 那么当vec的析构函数被调用时,数据会发生什么?
  • 我认为从技术上讲,您可以通过创建特殊分配器来做到这一点,但恐怕不会更糟。
  • 如果您不需要调整数组大小,那么另一个选项是使用unique_ptr&lt;int[]&gt; 而不是vector。您可能还需要跟踪大小,所以可能是pair&lt;int, unique_ptr&lt;int[]&gt;&gt;。 (这假设getArray 使用new[] 分配内存。否则您将需要unique_ptr 的自定义删除器)
  • @user19448 - I expect the data to be removed 向量知道如何删除它已分配的项目。它不知道如何从放置在其中的外来物品中删除物品(如果您尝试这样做)。最好按照其他人的建议使用智能指针。
  • 如果内存是在其他dll中分配的,也应该在那里释放。所以你必须使用库接口以任何方式释放这个内存......

标签: c++ arrays vector


【解决方案1】:

如果调用者不拥有数据(即不负责删除它),那么最简单的选择可能是编写类似容器的包装器:

template <typename T>
struct array_wrapper
{
  typedef T* iterator;
  typedef const T* const_iterator;
  array_wrapper(T* begin, T* end) : data_(begin), size_(end-begin) {}
  iterator begin() { return data_; }
  iterator end() { return data_ + size_; }
  const_iterator begin() const { return data_; }
  const_iterator end() const { return data_ + size_; }
  size_t size() const { return size_; }
  T& operator[](size_t i) { return _data[i]; }
  const T& operator[](size_t i) const { return _data[i]; }
  void swap(array_wrapper& other) { 
    std::swap(size_, other.size_);
    std::swap(data_, other.data_);
  }
 private:
  T* data_;
  size_t size_;
};

然后

array_wrapper<int> vec(array, array+sizeArr);

它具有std::vector 的许多功能,但不拥有基础数据,并且不支持会导致调整大小或重新分配的操作。

【讨论】:

  • 我认为这非常适合我的用例。正如其他人所建议的,我还将研究智能指针。 and supports no operations that would result in resizing or re-allocating 这对我来说很好。
  • @user19448 智能指针的特点是它们以一种或另一种方式承担所有权。
  • @user19448 请注意,如果您在完成后需要delete[] 指针,则需要向此类型添加一个析构函数,以便正确执行此操作。 (或者你可以花点心思制作模板参数template &lt;typename T, typename Deleter = std::default_delete&lt;T[]&gt;&gt;,这样如果你不负责删除指针,你就可以使用无操作删除器。)
【解决方案2】:

为什么你甚至用 int 指针来分配内存? 很有可能你没有理由这样做。

如果你有一个支持 c++11 的编译器,应该可以用 std::vector vec{array}; 初始化向量。 或者,如果您不再需要该数组,只需将其删除并将该数组的引用推送到该向量

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    • 2020-10-03
    • 2012-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多