| Index: boost/pool/pool.hpp |
| =================================================================== |
| --- boost/pool/pool.hpp (revision 78317) |
| +++ boost/pool/pool.hpp (revision 78326) |
| @@ -27,4 +27,6 @@ |
| #include <boost/pool/poolfwd.hpp> |
| |
| +// std::numeric_limits |
| +#include <boost/limits.hpp> |
| // boost::integer::static_lcm |
| #include <boost/integer/common_factor_ct.hpp> |
| @@ -358,4 +360,11 @@ |
| } |
| |
| + size_type max_chunks() const |
| + { //! Calculated maximum number of memory chunks that can be allocated in a single call by this Pool. |
| + size_type partition_size = alloc_size(); |
| + size_type POD_size = integer::static_lcm<sizeof(size_type), sizeof(void *)>::value + sizeof(size_type); |
| + return (std::numeric_limits<size_type>::max() - POD_size) / alloc_size(); |
| + } |
| + |
| static void * & nextof(void * const ptr) |
| { //! \returns Pointer dereferenced. |
| @@ -377,5 +388,7 @@ |
| //! the first time that object needs to allocate system memory. |
| //! The default is 32. This parameter may not be 0. |
| - //! \param nmax_size is the maximum number of chunks to allocate in one block. |
| + //! \param nmax_size is the maximum number of chunks to allocate in one block. |
| + set_next_size(nnext_size); |
| + set_max_size(nmax_size); |
| } |
| |
| @@ -400,7 +413,7 @@ |
| } |
| void set_next_size(const size_type nnext_size) |
| - { //! Set number of chunks to request from the system the next time that object needs to allocate system memory. This value should never be set to 0. |
| - //! \returns nnext_size. |
| - next_size = start_size = nnext_size; |
| + { //! Set number of chunks to request from the system the next time that object needs to allocate system memory. This value should never be set to 0. |
| + BOOST_USING_STD_MIN(); |
| + next_size = start_size = min BOOST_PREVENT_MACRO_SUBSTITUTION(nnext_size, max_chunks()); |
| } |
| size_type get_max_size() const |
| @@ -410,5 +423,6 @@ |
| void set_max_size(const size_type nmax_size) |
| { //! Set max_size. |
| - max_size = nmax_size; |
| + BOOST_USING_STD_MIN(); |
| + max_size = min BOOST_PREVENT_MACRO_SUBSTITUTION(nmax_size, max_chunks()); |
| } |
| size_type get_requested_size() const |
| @@ -713,7 +727,7 @@ |
| BOOST_USING_STD_MIN(); |
| if(!max_size) |
| - next_size <<= 1; |
| + set_next_size(next_size << 1); |
| else if( next_size*partition_size/requested_size < max_size) |
| - next_size = min BOOST_PREVENT_MACRO_SUBSTITUTION(next_size << 1, max_size*requested_size/ partition_size); |
| + set_next_size(min BOOST_PREVENT_MACRO_SUBSTITUTION(next_size << 1, max_size * requested_size / partition_size)); |
| |
| // initialize it, |
| @@ -753,7 +767,7 @@ |
| BOOST_USING_STD_MIN(); |
| if(!max_size) |
| - next_size <<= 1; |
| + set_next_size(next_size << 1); |
| else if( next_size*partition_size/requested_size < max_size) |
| - next_size = min BOOST_PREVENT_MACRO_SUBSTITUTION(next_size << 1, max_size*requested_size/ partition_size); |
| + set_next_size(min BOOST_PREVENT_MACRO_SUBSTITUTION(next_size << 1, max_size * requested_size / partition_size)); |
| |
| // initialize it, |
| @@ -797,4 +811,6 @@ |
| //! \returns Address of chunk n if allocated ok. |
| //! \returns 0 if not enough memory for n chunks. |
| + if (n > max_chunks()) |
| + return 0; |
| |
| const size_type partition_size = alloc_size(); |
| @@ -845,7 +861,7 @@ |
| BOOST_USING_STD_MIN(); |
| if(!max_size) |
| - next_size <<= 1; |
| + set_next_size(next_size << 1); |
| else if( next_size*partition_size/requested_size < max_size) |
| - next_size = min BOOST_PREVENT_MACRO_SUBSTITUTION(next_size << 1, max_size*requested_size/ partition_size); |
| + set_next_size(min BOOST_PREVENT_MACRO_SUBSTITUTION(next_size << 1, max_size * requested_size / partition_size)); |
| |
| // insert it into the list, |
| Index: libs/pool/test/test_bug_6701.cpp |
| =================================================================== |
| --- libs/pool/test/test_bug_6701.cpp (revision 78326) |
| +++ libs/pool/test/test_bug_6701.cpp (revision 78326) |
| @@ -0,0 +1,27 @@ |
| +/* Copyright (C) 2012 Étienne Dupuis |
| +* |
| +* Use, modification and distribution is subject to the |
| +* Boost Software License, Version 1.0. (See accompanying |
| +* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) |
| +*/ |
| + |
| +// Test of bug #6701 (https://svn.boost.org/trac/boost/ticket/6701) |
| + |
| +#include <boost/pool/object_pool.hpp> |
| +#include <boost/limits.hpp> |
| + |
| +int main() |
| +{ |
| + boost::pool<> p(1024, std::numeric_limits<size_t>::max() / 768); |
| + |
| + void *x = p.malloc(); |
| + BOOST_ASSERT(!x); |
| + |
| + BOOST_ASSERT(std::numeric_limits<size_t>::max() / 1024 >= p.get_next_size()); |
| + BOOST_ASSERT(std::numeric_limits<size_t>::max() / 1024 >= p.get_max_size()); |
| + |
| + void *y = p.ordered_malloc(std::numeric_limits<size_t>::max() / 768); |
| + BOOST_ASSERT(!y); |
| + |
| + return 0; |
| +} |