gpt4 book ai didi

c++ - 如何从 boost 共享内存 vector 中获取字符串,而不会从检索到的字符串的构造函数中触发共享内存中的分配?

转载 作者:太空狗 更新时间:2023-10-29 20:24:47 25 4
gpt4 key购买 nike

给定这些类型(来自 here,或多或少):

typedef boost::interprocess::managed_shared_memory::segment_manager SegmentManager;
typedef boost::interprocess::allocator<char, SegmentManager> CharAllocator;

typedef boost::interprocess::basic_string<char, std::char_traits<char>, CharAllocator> ShmString;

typedef boost::interprocess::allocator<ShmString, SegmentManager> StringAllocator;

typedef boost::interprocess::vector<ShmString, StringAllocator> ShmStringVector;

每当我从 ShmStringVector 中检索 ShmString 时,我的共享内存段的可用大小就会减少。

我认为发生的情况是,无论何时构建 ShmString,即使作为堆栈变量,它也会在共享内存段内分配空间。

ShmString 超出范围时,内存将被返回。但是,如果我的段容量接近极限,我不希望访问冒着导致共享内存段溢出的风险。

如何在不触发另一次分配的情况下取出字符串?

在下面的例子中,我试过了

//shared mem segment previously created with 1,000,000 bytes allocated
managed_shared_memory segment(open_only, "somename");
CharAllocator charAllocator(segment.get_segment_manager());
ShmStringVector *vec = segment.find<ShmStringVector>("somevectorname").first;

vec->push_back(" ... big string ..." ); // I can push a const char*
size_t sizeAfterInsertion = segment.get_free_memory();

ShmString res1 = vec->at(0); //works, but steals memory from shared memory, at least temporarily !
const char* res2 = vec->at(0); //compiler error
std::string res3 = vec->at(0); //compiler error
size_t sizeAfterGet = segment2.get_free_memory();
size_t diff = sizeAfterInsertion - sizeAfterGet;

我通过声明 ShmString 向自己证明了内存被占用了...

std::string size 170,     
before ins: 999232, after ins: 998976, shared memory taken by ins: 256
after get: 998768, shared memory taken by get: 208

最佳答案

正如 Wug 提到的,您可以使用引用。

字符串类型之间的转换/赋值:

如果你真的想要一个拷贝,在共享内存之外,复制到一个常规(或其他分配器)字符串:

std::string copied(vec2->at(0).begin(), vec2->at(0).end());

当然,反之亦然:

vec2[0].assign(copied.begin(), copied.end());
// Or
vec2->emplace_back({copied.begin(), copied.end()});

等等

直接在共享内存上使用流

另请注意,有 streaming support对于 Boost 进程间:

typedef allocator<int, managed_shared_memory::segment_manager>
IntAllocator;
typedef allocator<char, managed_shared_memory::segment_manager>
CharAllocator;
typedef vector<int, IntAllocator> MyVector;
typedef basic_string
<char, std::char_traits<char>, CharAllocator> MyString;
typedef basic_vectorstream<MyString> MyStringStream;

现在您可以使用 MyVectorStream 读取/写入共享内存字符串。它类似于 std::stringstream 但无需先将数据复制到流中。

例如将一些数据写入 vector :

   //Create the stream. To create the internal shared memory
//basic_string we need to pass the shared memory allocator as
//a constructor argument
MyStringStream mystringstream(CharAllocator(segment.get_segment_manager()));

//Reserve the internal string
mystringstream.reserve(100*5);

//Write all vector elements as text in the internal string
//Data will be directly written in shared memory, because
//internal string's allocator is a shared memory allocator
for(std::size_t i = 0, max = myvector->size(); i < max; ++i){
mystringstream << (*myvector)[i] << std::endl;
}

并将其读回以将其直接复制到另一个共享内存字符串中:

  //Auxiliary vector to compare original data
MyVector *myvector2 =
segment.construct<MyVector>("MyVector2")
(IntAllocator(segment.get_segment_manager()));

//Avoid reallocations
myvector2->reserve(100);

//Extract all values from the internal
//string directly to a shared memory vector.
std::istream_iterator<int> it(mystringstream), itend;
std::copy(it, itend, std::back_inserter(*myvector2));

//Compare vectors
assert(std::equal(myvector->begin(), myvector->end(), myvector2->begin()));

这取自文档示例,您可以在[ Live On Coliru]( http://coliru.stacked-crooked.com/a/7f1f450ac11edd4a

关于c++ - 如何从 boost 共享内存 vector 中获取字符串,而不会从检索到的字符串的构造函数中触发共享内存中的分配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26310048/

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