- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
在尝试写入一段使用 shared_memory_segment
以写入“共享内存”的(可移植)C++ 代码时,我遇到了 boost::interprocess::bad_alloc
几次。来自Boost documentation :
This exception is thrown when a memory request can't be fulfilled.
所以,我一定是分配的内存太少了。下面是代码(仅用于编写,因为阅读此处无关紧要):
shared_memory.h:
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <string>
#include <exception>
namespace my_shared_memory
{
typedef boost::interprocess::allocator<char, boost::interprocess::managed_shared_memory::segment_manager> CharAllocator;
typedef boost::interprocess::basic_string<char, std::char_traits<char>, CharAllocator> IPCString;
typedef boost::interprocess::allocator<IPCString, boost::interprocess::managed_shared_memory::segment_manager> StringAllocator;
typedef boost::interprocess::vector<IPCString, StringAllocator> ShmVector;
bool write_to_memory(std::string wsuid, std::string loop_val, std::string should_intercept, std::string post_data) ;
const std::string shm_prefix = "shm_";
const std::string mutex_prefix = "mtx_";
}
共享内存.cpp:
#include "shared_memory.h"
namespace apl_shared_memory
{
bool write_to_memory(std::string wsuid, std::string loop_val, std::string should_intercept, std::string post_data)
{
bool ret_val;
std::string shm_name = shm_prefix + wsuid;
std::string mtx_name = mutex_prefix + wsuid;
boost::interprocess::named_mutex named_mtx{boost::interprocess::open_or_create, mtx_name.c_str()};
size_t size = (sizeof(loop_val) + loop_val.size() + sizeof(should_intercept) + should_intercept.size() + sizeof post_data + post_data.size()) * 5;
try
{
named_mtx.lock();
boost::interprocess::shared_memory_object::remove(shm_name.c_str());
boost::interprocess::managed_shared_memory segment(boost::interprocess::create_only, shm_name.c_str(), size);
CharAllocator charallocator (segment.get_segment_manager());
StringAllocator stringallocator(segment.get_segment_manager());
IPCString shm_loop_val(charallocator);
IPCString shm_should_intercept(charallocator);
IPCString shm_intercepted_data(charallocator);
shm_loop_val = loop_val.c_str();
shm_should_intercept = should_intercept.c_str();
shm_intercepted_data = post_data.c_str();
segment.destroy<ShmVector>("ShmVector");
ShmVector *shmVector = segment.construct<ShmVector>("ShmVector")(stringallocator);
shmVector->clear();
shmVector->push_back(shm_loop_val);
shmVector->push_back(shm_should_intercept);
shmVector->push_back(shm_intercepted_data);
named_mtx.unlock();
ret_val = true;
} catch(const std::exception& ex)
{
ret_val = false;
named_mtx.unlock();
boost::interprocess::shared_memory_object::remove(shm_name.c_str());
}
named_mtx.unlock();
return ret_val;
}
}
是的,我知道我不需要在所有三个地方调用 unlock
。
问题似乎在行中:
size_t size = (sizeof(loop_val) + loop_val.size() + sizeof(should_intercept) + should_intercept.size() + sizeof post_data + post_data.size()) * 5;
我认为添加时间 5
有点矫枉过正,但事实显然并非如此。此代码在带有 gcc 6.3.0 的 Debian 9 和带有 Microsoft Visual Studio 2015 Community 的 Windows 10 上运行良好。但是,在使用 Xcode 10.1 的 MacOS 上,当我尝试在 vector 中插入第一个元素时,我得到了 boost::interprocess::bad_alloc
。该解决方案似乎将大小乘以 10 而不是 5,但这看起来很浪费。
我添加了 segment.get_free_memory
调用并确定对于包含以下三个字符串(不带引号)的 vector
"true" "true" ""
我需要 512 字节的 Xcode。 sizeof
运算符分别为 IPCString
、std::string
和 ShmVector
返回 32、24 和 32。因此,似乎我需要 32+4
字节来表示一个“真”字符串,而 32
来表示空字符串。在那里添加 ShmVector,结构本身需要 36+36+32+32=136
字节。我使用 sizeof(std::string)
计算了大小,这里是 24(疏忽),所以得到 (28+28+24)*5 = 400
,这里还不够。
我的问题是如何确定该段需要多少内存?我要写入该段的数据在函数被调用时是已知的,因此是它的大小。 p>
编辑:我将大小更改为:
size_t size = (sizeof(IPCString) + loop_val.size() + sizeof(IPCString) + should_intercept.size() + sizeof(IPCString) + post_data.size() + sizeof(ShmVector)) * 2 + 500;
到目前为止,还不错。在我完成对段的写入后,我的可用空间总是少于 500
字节。我尝试过各种数据大小,从不到 100 字节到 3 兆字节不等。我试过不乘以 2
但在那种情况下,当我尝试插入大数据 block 时,程序崩溃,因为 500
额外的字节没有提供足够的回旋余地。
如果几天后没有答案,我会将此修改作为答案发布。
最佳答案
您对字体大小的等效性做出了许多假设。 c 字符串的内存使用与 std::string 的内存使用不同,后者与 IPCString 的内存使用不同,后者实际上是 vector。 ,因此您对大小或长度不感兴趣,但对容量感兴趣。
从马口调整组件大小:采用 IPCString
变量的 sizeof
而不是 std::string
变量,并且采用 shm_loop_val.capacity() + shm_should_intercept.capacity() + shm_intercepted_data.capacity()
而不是调整 std::strings
的大小!
你应该更接近:
size_t size = (3 * sizeof(IPCString) + sizeof(ShmVector) + shm_loop_val.capacity() +
shm_should_intercept.capacity() + shm_intercepted_data.capacity();
Boost 实现也可能对您的数据进行字对齐,但我开始意识到这不太可能。这看起来像是连载的。我们可以调查您是否仍有问题。
关于c++ - boost IPC managed_memory_segment bad_alloc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54256450/
在尝试写入一段使用 shared_memory_segment 以写入“共享内存”的(可移植)C++ 代码时,我遇到了 boost::interprocess::bad_alloc 几次。来自Boos
我是一名优秀的程序员,十分优秀!