gpt4 book ai didi

c++ - 从 std::vector 接管内存

转载 作者:可可西里 更新时间:2023-11-01 16:17:51 26 4
gpt4 key购买 nike

我使用一个处理大量数据的外部库。数据由原始指针加上长度传入。该库不声明指针的所有权,但会在处理完数据后调用提供的回调函数(具有相同的两个参数)。

使用 std::vector<T> 可以方便地准备数据,我宁愿不放弃这种便利。复制数据是完全不可能的。因此,我需要一种方法来“接管”std::vector<T> 拥有的内存缓冲区。 ,并(稍后)在回调中取消分配它。

我目前的解决方案如下所示:

std::vector<T> input = prepare_input();
T * data = input.data();
size_t size = input.size();
// move the vector to "raw" storage, to prevent deallocation
alignas(std::vector<T>) char temp[sizeof(std::vector<T>)];
new (temp) std::vector<T>(std::move(input));
// invoke the library
lib::startProcesing(data, size);

并且,在回调函数中:

void callback(T * data, size_t size) {
std::allocator<T>().deallocate(data, size);
}

此解决方案有效,因为标准分配器的 deallocate函数忽略它的第二个参数(元素计数)并简单地调用 ::operator delete(data) .如果没有,可能会发生坏事,因为 size输入 vector 的可能比它的 capacity 小很多.

我的问题是:是否有一种可靠的方式(根据 C++ 标准)接管 std::vector 的缓冲区?并在稍后“手动”发布它?

最佳答案

您不能从 vector 中获取内存的所有权,但您可以通过另一种方式解决您的潜在问题。

以下是我的处理方式 - 由于静态全局变量且不是线程安全的,它有点老套,但可以通过围绕对 registry 的访问进行一些简单的锁定来做到这一点对象。

static std::map<T*, std::vector<T>*> registry;
void my_startProcessing(std::vector<T> * data) {
registry.put(data->data(), data);
lib::startProcesing(data->data(), data->size());
}

void my_callback(T * data, size_t length) {
std::vector<T> * original = registry.get(data);
delete original;
registry.remove(data);
}

现在你可以做

std::vector<T> * input = ...
my_startProcessing(input);

但要小心! 如果在调用 my_startProcessing 后向输入添加/删除元素,将会发生不好的事情。 - 库的缓冲区可能无效。 (您可能被允许更改 vector 中的值,因为我相信这会正确地写入数据,但这也取决于库允许的内容。)

此外,如果T,这也不起作用= boolstd::vector<bool>::data()不起作用。

关于c++ - 从 std::vector 接管内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27160953/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com