是否可以在不复制的情况下从 std::vector 中提取数据? (并让向量忘记它)

Is it possible to extract data from std::vector without copying it? (and make the vector forget it)

我有一个 std::vector<byte> 对象,我想从中提取数据而不复制。 它可能包含数兆字节的数据。所以,如果我复制数据,我会失去性能。 是否可以从向量中提取数据并使其忘记数据,也就是说,它不会在销毁后为数据释放内存? 希望得到您的帮助! 提前致谢!

P.S:在这种情况下,extract 意味着只获取指向数据的原始指针并让 vector 忘记它(即在销毁后不要释放内存)

不,据我所知,无法从矢量中提取 部分 数据。

它与在内存的连续部分提供数据的向量结构不兼容。 std::vector记忆是连续的,所以如果有可能将它的一部分记忆移动到另一个地方,你需要转移记忆的提醒以保持它的连续性。这本身就是一个巨大的负担。

个人建议通过pointer/reference传递main vector,需要的部分直接使用

如果您需要将std::vector整个数据移动到另一个地方,您可以使用std::move()来完成。您甚至可以使用 std::swap() 将 2 个向量的内容交换在一起。

I have a std::vector object and I want to extract data from it without copying

您可以移动一个向量的全部内容...到另一个向量中。 或者你可以交换两个向量的(内容)。

std::vector<byte> v = get_a_big_vector();
std::vector<byte> w = std::move(v); // now w owns the large allocation
std::vector<byte> x;
std::swap(x,y); // now x owns the large allocation, and w is empty

就是这样。您不能要求向量释放其存储空间,也不能以某种方式“获取”连续分配的一部分而不影响其余部分。

您可以移动分配一些子范围的元素,但如果元素是某种对象,并且状态存储在实例外部(例如,长 std::string),则这与复制唯一不同。

如果您真的需要只取一个子范围并释放其余部分,那么 vector 并不是真正正确的数据类型。为此设计了类似绳子的东西,或者您可以将单个连续向量拆分为 1Mb(或其他)块间接向量。这实际上类似于双端队列(尽管您也不能从 std::deque 窃取块)。

我认为最好的方法是使用面向对象的方法。您可以将 class 中的字节数据与其他信息(如标志)一起抽象出来,使它们被跳过或忘记:

class Data
{
public:
   Data(byte d)
   {
       data = d;
       forget = false;
   }
   byte data;
   bool forget;
}

然后只需将指向数据的向量指针添加到

vector<Data*> data;
data.push_back(new Data(1));    
data.push_back(new Data(2));
// and so on

您可以在不复制的情况下提取数据,只需获取指向数组特定元素的指针即可:

Data *d = data[index];
d->forget = true;

您可以使用忘记标志让它变得容易忘记。当然,在搜索向量时,您必须自己管理忘记标志。您可以使用 std::find_if 和 lamba 表达式来表示这只海豚。

请记住,当不再使用数据时,您必须释放内存。