最近我注意到以下陈述并非如此std::string s.
s.max_size() == s.get_allocator().max_size();
Run Code Online (Sandbox Code Playgroud)
我发现这很有意思,默认情况下std::string会使用std::allocator<char>它具有理论极限size_type(-1)(是的,我知道我假设2的补码,但这与实际问题无关).我知道实际的限制将远远小于此.在典型的32位x86系统上,内核将占用2GB(可能是1GB)的地址空间,从而留下更小的实际上限.
无论如何,GNU libstdc ++ std::basic_string<>::max_size()似乎返回相同的值,无论它使用什么分配器(如类似1073741820).
所以问题仍然存在,为什么不std::basic_string<>::max_size()回归get_allocator().max_size()呢?在我看来,这是假设的上限.如果分配很短,它只会扔一个std::bad_alloc,所以为什么不尝试?
这更像是一种好奇心,我只是想知道为什么这两者至少在这一个实现中被单独定义.
有没有人知道STL实现允许在使用之前将动态分配器传递给容器的实例.
方案是我们有一个通用内存分配器来管理许多内存池,并且对于我们想要从不同内存池分配每个实例的stl :: vector的每个实例.
标准STL实现的问题在于您只能在类型基础上定义内存池,即int类型的所有向量都将从同一个池中分配.
我已经将我们的默认stl :: allocator换成了一个有状态的那个,即我们想要分配这个实例的池,但这对于stl :: list来说效果不好,它在默认的ctor中分配东西.
由于与我们的库相关的原因,我们在ctor中没有所有对象的有效池,因此我们想在用户可以使用stl容器之前调用'set memory pool'函数.
有没有人遇到过支持这种事情的实现?
我观察到我的MSVC10副本带有似乎允许基于状态的分配器的容器,并编写了一个简单的池分配器,为特定类型分配池.但是,我发现如果_ITERATOR_DEBUG_LEVEL != 0MSVC向量从传递的分配器创建代理分配器(用于迭代器跟踪?),则使用代理,然后让代理超出范围,期望分配的内存保留.这会导致问题,因为我的分配器尝试在销毁时释放它的池.这是否允许C++ 0x标准?
代码大致如下:
class _Container_proxy{};
template<class T, class _Alloc>
class vector {
_Alloc _Alval;
public:
vector() {
// construct _Alloc<_Container_proxy> _Alproxy
typename _Alloc::template rebind<_Container_proxy>::other
_Alproxy(_Alval);
//allocate
this->_Myproxy = _Alproxy.allocate(1);
/*other stuff, but no deallocation*/
} //_Alproxy goes out of scope
~_Vector_val() { // destroy proxy
// construct _Alloc<_Container_proxy> _Alproxy
typename _Alloc::template rebind<_Container_proxy>::other
_Alproxy(_Alval);
/*stuff, but no allocation*/
_Alproxy.deallocate(this->_Myproxy, 1);
} //_Alproxy goes out of scope again
Run Code Online (Sandbox Code Playgroud) 我正在编写一个内存分配器,我想针对程序中最常见的模式(对malloc和free的调用)进行测试.
是否已经确定了内存管理中的常见模式?如果是这样,有没有这方面的好书或网络资源?
我对单线程程序的模式以及多线程程序都很感兴趣.
附加:
我目前认为一些典型的数学模型可以描述这种模式.
sin/cos函数可以描述生产者(malloc)/消费者(免费)算法,其中生产者必须完成生产其所有产品,然后才能由消费者出售.
斐波那契序列可以描述一个程序,其中malloc(ed)区域的数量自然增长(例如,在模拟一些现实世界的问题时).
如果您有任何其他想法,那将非常感激.但同样,最好还有一本书/论文/博士论文.
我注意到allocator只能分配类型的对象T并保留大小的内存块n * sizeof(T).std::list<T>但是,类型内部的链接列表节点不一定是类型的对象T,也不一定是与T对象相同的大小.在那种情况下,如何std::list使用std::allocator分配内存?
我希望有一个std::vector对象,使用分配的对象boost::pool.这是正确的:
class MyClass
{
private:
double data;
public:
MyClass(double d) : data(d) { }
};
int main()
{
std::vector<MyClass, boost::fast_pool_allocator<MyClass> > vect;
vect.push_back(4.5);
vect.push_back(9.8); //Are these being stored in a pool now?
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这段代码有效,但我不完全确定原因.我对分配器的概念很陌生,但是如果我理解正确的话,这就是std::vector使用池而不是默认分配器,因此在向量中创建的任何元素都将从池中创建.
我不太确定的是:
游泳池在哪里?
我将如何直接访问池(例如释放内存)?
是否fast_pool_allocator包含池,或者我是否需要单独创建池并以某种方式告诉分配器使用它.
问题出在标题中.这是允许容器,还是保证分配器的方法被调用,即使对象是可以构造/可破坏的?
我确实试图搜索这个,但空手而归......但如果它是重复的,请告诉我.
我想创建unordered_map(因为我特别想要一个哈希映射).我想在开头分配它的最大尺寸(根据我的约束).
所以,如果我想分配256个条目,每个条目的大小是1B(只是一个例子.假设1Byte包括Key和Value).然后我的unordered_map键+条目的总大小是256B.我想在分配器中预先分配256B.
然后,当unordered_map将调用allocate()/时deallocate(),allocator将从已分配的内存中给它1B.
typedef boost::unordered::unordered_map<int, MyClass, boost::hash<int>, std::equal_to<MyClass>, ??? > > myMap
它是否存在于BOOST中?或者别的地方?
----编辑----
正如我所看到的(感谢此处的答案) - 我的问题有两个解决方案:
实现一个allocator,持有一个boost::pool<>.这pool是在allocator构造函数中构建的.当allocate()被调用时unordered_map,它实际上调用pool.malloc(),并且当deallocate()调用unordered_map它时,它实际调用pool.free().
使用已经实现的allocator,pool_allocator如下所示:
typedef pool_allocator<std::pair<MyKey, MyClass>, boost::default_user_allocator_new_delete, boost::mutex, 1024 >) MyAllocator;
typedef unordered_map<MyKey, MyClass, hash, eq, MyAllocator> MyUnorderedMap;
秒选项对我来说仍然不清楚,因为:
a.我只能声明一个MyUnorderedMap吗?
湾 我怎样才能申报使用不同的新MyUnorderedMap next_block大小比1024在运行时间?
似乎C++ STL容器要求提供的分配器类型的value_type与STL容器的value_type相同
要求:allocator_- type :: value_type与X :: value_type相同.
但是,以下使用字符串向量但带有双精度分配器的代码在VS 2012和g ++ 4.4.7上运行正常.在g ++上,valgrind也不会产生任何错误.
int main()
{
typedef vector<std::string, std::allocator<double> > StringList;
StringList s;
for(int i=0; i < 100; i++){
stringstream ss;
ss << i;
s.push_back(ss.str());
}
for(StringList::iterator it = s.begin(); it != s.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我假设分配器正在内部反弹到容器的value_type的分配器(虽然可能我错了).
我的问题是我误读了C++规范,实际上所有容器都会"重新绑定"提供的分配器以使用他们想要的类型吗?或者这只是一种常见的做法,但不能保证.
基本上我可以依靠这个"功能",容器将始终采用我提供的任何分配器(任何类型)并使其适用于该容器的value_type?
这是我用来测试的代码:
#include <iostream>
#include <boost/interprocess/managed_mapped_file.hpp>
#include <boost/container/map.hpp>
#include <boost/interprocess/managed_external_buffer.hpp>
#include <boost/interprocess/allocators/node_allocator.hpp>
#include <boost/container/vector.hpp>
namespace bi = boost::interprocess;
int main() {
bi::managed_mapped_file mmfile(bi::open_or_create, "map_iv.dat", 10000000);
typedef bi::allocator<int, bi::managed_mapped_file::segment_manager> int_allocator;
typedef boost::container::vector<int, int_allocator> MyVec;
typedef std::pair<const std::string, MyVec> MyPair;
typedef std::less<std::string> MyLess;
typedef bi::node_allocator<MyPair, bi::managed_mapped_file::segment_manager> node_allocator_t;
typedef boost::container::map<std::string, MyVec, std::less<std::string>, node_allocator_t> MyMap;
MyMap * mapptr = mmfile.find_or_construct<MyMap>("mymap")(mmfile.get_segment_manager());
(*mapptr)["Hello"].push_back(17);
long long s = mapptr->size();
std::cout << s << ' ';
std::cout << (*mapptr)["World"][0] << ' ';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我在Visual Studio 2017中收到此错误消息:
boost_1_69_0\boost\container\vector.hpp(294): …Run Code Online (Sandbox Code Playgroud) allocator ×10
c++ ×8
boost ×3
stl ×3
boost-pool ×1
c++11 ×1
containers ×1
scope ×1
stdstring ×1
vector ×1
visual-c++ ×1