【问题标题】:How to make a std::vector<T> use an existing T* array without copying those values? [duplicate]如何使 std::vector<T> 使用现有的 T* 数组而不复制这些值? [复制]
【发布时间】:2017-07-28 21:56:49
【问题描述】:

我有一个std::vector&lt;unsigned char&gt; vec 和一个大小为 (len) 的 (unsigned char) 的预分配连续缓冲区,我知道它是存储在名为 startunsigned char* 变量中的开始。我知道我可以使用std::copy(start,start+len,vec.begin()) 将它们复制到向量中,但是我可以不复制就这样做吗?我可以让vec.begin() 指向开始指针吗?我已经在内存中分配了所有值,我不想将它们复制到向量中,因为我有内存限制。

指针和长度是通过外部 API 提供给我的,所以我无法更改。

【问题讨论】:

  • 你能给我们一些代码吗?听起来您可能想要spanview
  • 请注意,std::copy(start,start+len,vec.begin()) 是未定义的行为,如果您尚未完成 vec.resize(len)
  • 坚持使用std::vector 构造函数。像这样:std::vector&lt;unsigned char&gt; vec (start, start + len);
  • @DimChtz 请注意,这确实会分配额外的内存
  • 这可以通过以一些非常、非常粗略的方式破解自定义分配器来实现。然而,这真的很恶心。更好的解决方案是:1)只需将其吸收并复制到向量中。这样做真的是世界末日吗? 2)放弃拥有一个向量。 C++ 中传递这类东西的规范方法是通过成对的迭代器,这个例子实际上说明了原因。

标签: c++ stdvector


【解决方案1】:

vector 没有接口,可以让它拥有你预先存在的缓冲区的所有权。即使您可以通过使用提供此内存地址的自定义分配器将其硬塞到向量中,向量也会将其视为原始内存并覆盖它。

如果它必须是一个向量,那么如果没有复制,你就不走运了。

但是,现有缓冲区上的某种自适应视图可以在您的数组上提供类似容器的接口,而无需复制(例如 Justin 在 cmets 中建议的 gsl::span。)

gsl::span<int> s(myPtr, 4);

https://github.com/Microsoft/GSLhttp://codexpert.ro/blog/2016/03/07/guidelines-support-library-review-spant/

【讨论】:

  • 这将是重复目标的一个很好的答案(当然,您必须确保它被重写以适应它的上下文)
  • Microsoft 有一个array_view 类,并且有人提议将std::array_view 类添加到标准 STL。
【解决方案2】:

由于您想控制向量的内存分配,因此您需要创建自己的分配器类来执行此操作,并将其作为模板参数传递,如下所示:

std::vector<int, my_custom_allocator<int>> my_vector;

这是一个关于如何创建自己的分配器的好教程:The Standard Librarian: What Are Allocators Good For?

【讨论】:

    猜你喜欢
    • 2015-03-01
    • 2011-06-30
    • 1970-01-01
    • 2017-09-01
    • 2014-02-14
    • 1970-01-01
    • 2016-11-05
    • 1970-01-01
    • 2016-03-31
    相关资源
    最近更新 更多