是否可以在不复制的情况下从 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 表达式来表示这只海豚。
请记住,当不再使用数据时,您必须释放内存。
我有一个 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 表达式来表示这只海豚。
请记住,当不再使用数据时,您必须释放内存。